adron2 Опубликовано 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). Жду ответов. Спасибо. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 1 февраля, 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 слишком быстро? Изменено 1 февраля, 2010 пользователем photon Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
adron2 Опубликовано 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); или я не прав? Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
photon Опубликовано 2 февраля, 2010 · Жалоба Делайте как хотите. В любом случае, лучше пользоваться готовым API, чем изобретать свои велосипеды. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
adron2 Опубликовано 2 февраля, 2010 · Жалоба Делайте как хотите. В любом случае, лучше пользоваться готовым API, чем изобретать свои велосипеды. Ясно. Спасибо. Буду пробовать :) Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
bitbucket Опубликовано 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. Частая блокировка прерываний сильно ухудшает производительность. Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
Умник Опубликовано 2 февраля, 2010 · Жалоба А по хорошему нужно всего лишь прочитать это http://www.kernel.org/pub/linux/kernel/peo...king/index.html и не пытаться изобретать велосипед. Там рассмотрены все возможные варианты синхронизации. P.S.: Не обращайте внимания на дату документа. Он все еще очень актуален. делайте mutex lockВ softirq? Где нельзя спать? Ничего хорошего не получится. :( Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
vitalyb Опубликовано 2 февраля, 2010 · Жалоба В Linux 2.6 есть API для per-cpu счетчиков, если есть возможность - используйте их. http://lwn.net/Articles/22911/ Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...
bitbucket Опубликовано 2 февраля, 2010 (изменено) · Жалоба В softirq? Где нельзя спать? Ничего хорошего не получится. :(Я имел в виду не фунционал ядра, а тип семафора. Правильней даже spinlock, но без cli/sti. Конечно, в softirq любой sched() приведет к bug(scheduling_in_interrupt). Простой семафор для SMP делается через lock cmpxchg, тем более, что время, на которое делается блоировка не существенно. Но правильно придумать алгоритм, что бы вообще избежать лочек. Изменено 2 февраля, 2010 пользователем bitbucket Вставить ник Цитата Ответить с цитированием Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах More sharing options...