summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2006-07-22 15:37:43 +0200
committerJens Axboe <axboe@nelson.home.kernel.dk>2006-09-30 20:29:36 +0200
commit4a893e837bb470867d74c05d6c6b97bba5a96185 (patch)
treea8795f4422eac82679309e1f1f500789c3fd9bff
parentfc46379daf90dce57bf765c81d3b39f55150aac2 (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>
-rw-r--r--include/linux/elevator.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index cc81645a3e18..9c5a04f6114c 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