diff options
author | Jens Axboe <axboe@suse.de> | 2006-07-22 15:37:43 +0200 |
---|---|---|
committer | Jens Axboe <axboe@nelson.home.kernel.dk> | 2006-09-30 20:29:36 +0200 |
commit | 4a893e837bb470867d74c05d6c6b97bba5a96185 (patch) | |
tree | a8795f4422eac82679309e1f1f500789c3fd9bff /include/linux/elevator.h | |
parent | fc46379daf90dce57bf765c81d3b39f55150aac2 (diff) |
[PATCH] elevator: define ioc counting mechanism
None of the in-kernel primitives for handling "atomic" counting seem
to be a good fit. We need something that is essentially free for
incrementing/decrementing, while the read side may be more expensive
as we only ever need to do that when a device is removed from the
kernel.
Use a per-cpu variable for maintaining a per-cpu ioc count and define
a reading mechanism that just sums up the values.
Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'include/linux/elevator.h')
-rw-r--r-- | include/linux/elevator.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/elevator.h b/include/linux/elevator.h index cc81645a3e1..9c5a04f6114 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -1,6 +1,8 @@ #ifndef _LINUX_ELEVATOR_H #define _LINUX_ELEVATOR_H +#include <linux/percpu.h> + typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct bio *); @@ -178,4 +180,27 @@ enum { INIT_LIST_HEAD(&(rq)->donelist); \ } while (0) +/* + * io context count accounting + */ +#define elv_ioc_count_mod(name, __val) \ + do { \ + preempt_disable(); \ + __get_cpu_var(name) += (__val); \ + preempt_enable(); \ + } while (0) + +#define elv_ioc_count_inc(name) elv_ioc_count_mod(name, 1) +#define elv_ioc_count_dec(name) elv_ioc_count_mod(name, -1) + +#define elv_ioc_count_read(name) \ +({ \ + unsigned long __val = 0; \ + int __cpu; \ + smp_wmb(); \ + for_each_possible_cpu(__cpu) \ + __val += per_cpu(name, __cpu); \ + __val; \ +}) + #endif |