adron2 Posted February 1, 2010 Posted February 1, 2010 В модуле ядра линукс нужно крутить 8 счетчиков типа uint_32 Какой тип взаимной блокировки лучше использовать spin_lock_bh(&a->lock) a->counter1++; ..... a->counter8++; spin_unlock_bh(&a->lock) или же как в атомарных операциях unsigned long flags; local_irq_save(flags) a->counter1++; ..... a->counter8++; local_irq_restore(flags) счетчики крутятся в match функции match модуля для iptables(простая считалка пакетов типа ip_account). Жду ответов. Спасибо. Вставить ник Quote
photon Posted February 1, 2010 Posted February 1, 2010 (edited) В модуле ядра линукс нужно крутить 8 счетчиков типа uint_32счетчики крутятся в match функции match модуля для iptables(простая считалка пакетов типа ip_account). Жду ответов. Спасибо. Для счетчиков не важен порядок выполнения, а важна атомарность. Для атомарных целочисленных операций есть такое: #include <asm/atomic.h> atomic_t x1 = ATOMIC_INIT(0); int x; atomic_inc(&x1); x = atomic_read(&x1); Однако, не переполнятся ли uint_32 слишком быстро? Edited February 1, 2010 by photon Вставить ник Quote
adron2 Posted February 2, 2010 Author Posted February 2, 2010 В модуле ядра линукс нужно крутить 8 счетчиков типа uint_32счетчики крутятся в match функции match модуля для iptables(простая считалка пакетов типа ip_account). Жду ответов. Спасибо. Для счетчиков не важен порядок выполнения, а важна атомарность. Для атомарных целочисленных операций есть такое: #include <asm/atomic.h> atomic_t x1 = ATOMIC_INIT(0); int x; atomic_inc(&x1); x = atomic_read(&x1); Однако, не переполнятся ли uint_32 слишком быстро? не переполнятся. Они раз в 30 секунд будут сниматься. Про атомарность думал. Но в том же asm/atomic.h вот что за код: static inline int atomic_add_return(int i, atomic_t *v) { unsigned long flags; int temp; local_irq_save(flags); temp = v->counter; temp += i; v->counter = temp; local_irq_restore(flags); return temp; } static inline void atomic_inc(atomic_t *v) { atomic_add_return(1, v); } То есть поидее оптимальней будет сделать: unsigned long flags; local_irq_save(flags); counter1++; ................ counterN++; local_irq_restore(flags); или я не прав? Вставить ник Quote
photon Posted February 2, 2010 Posted February 2, 2010 Делайте как хотите. В любом случае, лучше пользоваться готовым API, чем изобретать свои велосипеды. Вставить ник Quote
adron2 Posted February 2, 2010 Author Posted February 2, 2010 Делайте как хотите. В любом случае, лучше пользоваться готовым API, чем изобретать свои велосипеды. Ясно. Спасибо. Буду пробовать :) Вставить ник Quote
bitbucket Posted February 2, 2010 Posted February 2, 2010 В модуле ядра линукс нужно крутить 8 счетчиков типа uint_32Какой тип взаимной блокировки лучше использовать ... счетчики крутятся в match функции match модуля для iptables(простая считалка пакетов типа ip_account). Если у вас не SMP система - блокировка не нужна вообще, ибо операция 'inc dword ptr ...' выполняется атомарно.Если все же SMP, то тут два варианта: 1. Если счетчиков не много, завести N комплектов счетчиков по числу ядер процессора, и на каждом ядре инкрементировать свой комплект, а результат получать суммированием по всем N комплектам счетчиков. В этом случае блокировок не будет вообще. Для абсолютно точного получения результата проще всего создать новый комплект нулевых счетчиков, и поменять его местами с текущим, причем операцию земены сделать атомарной через 'lock mov ...'. Соответственно полученый 'старый' комплект счетчиков обрабатывать, и нулить. 2. Если п1 не подходит (или не intel) - делайте mutex lock. Частая блокировка прерываний сильно ухудшает производительность. Вставить ник Quote
Умник Posted February 2, 2010 Posted February 2, 2010 А по хорошему нужно всего лишь прочитать это http://www.kernel.org/pub/linux/kernel/peo...king/index.html и не пытаться изобретать велосипед. Там рассмотрены все возможные варианты синхронизации. P.S.: Не обращайте внимания на дату документа. Он все еще очень актуален. делайте mutex lockВ softirq? Где нельзя спать? Ничего хорошего не получится. :( Вставить ник Quote
vitalyb Posted February 2, 2010 Posted February 2, 2010 В Linux 2.6 есть API для per-cpu счетчиков, если есть возможность - используйте их. http://lwn.net/Articles/22911/ Вставить ник Quote
bitbucket Posted February 2, 2010 Posted February 2, 2010 (edited) В softirq? Где нельзя спать? Ничего хорошего не получится. :(Я имел в виду не фунционал ядра, а тип семафора. Правильней даже spinlock, но без cli/sti. Конечно, в softirq любой sched() приведет к bug(scheduling_in_interrupt). Простой семафор для SMP делается через lock cmpxchg, тем более, что время, на которое делается блоировка не существенно. Но правильно придумать алгоритм, что бы вообще избежать лочек. Edited February 2, 2010 by bitbucket Вставить ник Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.