block,elevator: use new hashtable implementation
[linux-3.10.git] / include / linux / elevator.h
index 4d85797..7c5a7c9 100644 (file)
@@ -2,9 +2,12 @@
 #define _LINUX_ELEVATOR_H
 
 #include <linux/percpu.h>
+#include <linux/hashtable.h>
 
 #ifdef CONFIG_BLOCK
 
+struct io_cq;
+
 typedef int (elevator_merge_fn) (struct request_queue *, struct request **,
                                 struct bio *);
 
@@ -20,17 +23,19 @@ typedef void (elevator_bio_merged_fn) (struct request_queue *,
 typedef int (elevator_dispatch_fn) (struct request_queue *, int);
 
 typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
-typedef int (elevator_queue_empty_fn) (struct request_queue *);
 typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
 typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
 typedef int (elevator_may_queue_fn) (struct request_queue *, int);
 
-typedef int (elevator_set_req_fn) (struct request_queue *, struct request *, gfp_t);
+typedef void (elevator_init_icq_fn) (struct io_cq *);
+typedef void (elevator_exit_icq_fn) (struct io_cq *);
+typedef int (elevator_set_req_fn) (struct request_queue *, struct request *,
+                                  struct bio *, gfp_t);
 typedef void (elevator_put_req_fn) (struct request *);
 typedef void (elevator_activate_req_fn) (struct request_queue *, struct request *);
 typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *);
 
-typedef void *(elevator_init_fn) (struct request_queue *);
+typedef int (elevator_init_fn) (struct request_queue *);
 typedef void (elevator_exit_fn) (struct elevator_queue *);
 
 struct elevator_ops
@@ -46,12 +51,14 @@ struct elevator_ops
        elevator_activate_req_fn *elevator_activate_req_fn;
        elevator_deactivate_req_fn *elevator_deactivate_req_fn;
 
-       elevator_queue_empty_fn *elevator_queue_empty_fn;
        elevator_completed_req_fn *elevator_completed_req_fn;
 
        elevator_request_list_fn *elevator_former_req_fn;
        elevator_request_list_fn *elevator_latter_req_fn;
 
+       elevator_init_icq_fn *elevator_init_icq_fn;     /* see iocontext.h */
+       elevator_exit_icq_fn *elevator_exit_icq_fn;     /* ditto */
+
        elevator_set_req_fn *elevator_set_req_fn;
        elevator_put_req_fn *elevator_put_req_fn;
 
@@ -59,7 +66,6 @@ struct elevator_ops
 
        elevator_init_fn *elevator_init_fn;
        elevator_exit_fn *elevator_exit_fn;
-       void (*trim)(struct io_context *);
 };
 
 #define ELV_NAME_MAX   (16)
@@ -75,25 +81,35 @@ struct elv_fs_entry {
  */
 struct elevator_type
 {
-       struct list_head list;
+       /* managed by elevator core */
+       struct kmem_cache *icq_cache;
+
+       /* fields provided by elevator implementation */
        struct elevator_ops ops;
+       size_t icq_size;        /* see iocontext.h */
+       size_t icq_align;       /* ditto */
        struct elv_fs_entry *elevator_attrs;
        char elevator_name[ELV_NAME_MAX];
        struct module *elevator_owner;
+
+       /* managed by elevator core */
+       char icq_cache_name[ELV_NAME_MAX + 5];  /* elvname + "_io_cq" */
+       struct list_head list;
 };
 
+#define ELV_HASH_BITS 6
+
 /*
  * each queue has an elevator_queue associated with it
  */
 struct elevator_queue
 {
-       struct elevator_ops *ops;
+       struct elevator_type *type;
        void *elevator_data;
        struct kobject kobj;
-       struct elevator_type *elevator_type;
        struct mutex sysfs_lock;
-       struct hlist_head *hash;
        unsigned int registered:1;
+       DECLARE_HASHTABLE(hash, ELV_HASH_BITS);
 };
 
 /*
@@ -101,9 +117,8 @@ struct elevator_queue
  */
 extern void elv_dispatch_sort(struct request_queue *, struct request *);
 extern void elv_dispatch_add_tail(struct request_queue *, struct request *);
-extern void elv_add_request(struct request_queue *, struct request *, int, int);
-extern void __elv_add_request(struct request_queue *, struct request *, int, int);
-extern void elv_insert(struct request_queue *, struct request *, int);
+extern void elv_add_request(struct request_queue *, struct request *, int);
+extern void __elv_add_request(struct request_queue *, struct request *, int);
 extern int elv_merge(struct request_queue *, struct request **, struct bio *);
 extern void elv_merge_requests(struct request_queue *, struct request *,
                               struct request *);
@@ -111,7 +126,6 @@ extern void elv_merged_request(struct request_queue *, struct request *, int);
 extern void elv_bio_merged(struct request_queue *q, struct request *,
                                struct bio *);
 extern void elv_requeue_request(struct request_queue *, struct request *);
-extern int elv_queue_empty(struct request_queue *);
 extern struct request *elv_former_request(struct request_queue *, struct request *);
 extern struct request *elv_latter_request(struct request_queue *, struct request *);
 extern int elv_register_queue(struct request_queue *q);
@@ -119,14 +133,15 @@ extern void elv_unregister_queue(struct request_queue *q);
 extern int elv_may_queue(struct request_queue *, int);
 extern void elv_abort_queue(struct request_queue *);
 extern void elv_completed_request(struct request_queue *, struct request *);
-extern int elv_set_request(struct request_queue *, struct request *, gfp_t);
+extern int elv_set_request(struct request_queue *q, struct request *rq,
+                          struct bio *bio, gfp_t gfp_mask);
 extern void elv_put_request(struct request_queue *, struct request *);
 extern void elv_drain_elevator(struct request_queue *);
 
 /*
  * io scheduler registration
  */
-extern void elv_register(struct elevator_type *);
+extern int elv_register(struct elevator_type *);
 extern void elv_unregister(struct elevator_type *);
 
 /*
@@ -138,7 +153,7 @@ extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);
 extern int elevator_init(struct request_queue *, char *);
 extern void elevator_exit(struct elevator_queue *);
 extern int elevator_change(struct request_queue *, const char *);
-extern int elv_rq_merge_ok(struct request *, struct bio *);
+extern bool elv_rq_merge_ok(struct request *, struct bio *);
 
 /*
  * Helper functions.
@@ -149,7 +164,7 @@ extern struct request *elv_rb_latter_request(struct request_queue *, struct requ
 /*
  * rb support functions.
  */
-extern struct request *elv_rb_add(struct rb_root *, struct request *);
+extern void elv_rb_add(struct rb_root *, struct request *);
 extern void elv_rb_del(struct rb_root *, struct request *);
 extern struct request *elv_rb_find(struct rb_root *, sector_t);
 
@@ -167,6 +182,8 @@ extern struct request *elv_rb_find(struct rb_root *, sector_t);
 #define ELEVATOR_INSERT_BACK   2
 #define ELEVATOR_INSERT_SORT   3
 #define ELEVATOR_INSERT_REQUEUE        4
+#define ELEVATOR_INSERT_FLUSH  5
+#define ELEVATOR_INSERT_SORT_MERGE     6
 
 /*
  * return values from elevator_may_queue_fn
@@ -192,22 +209,5 @@ enum {
        INIT_LIST_HEAD(&(rq)->csd.list);        \
        } while (0)
 
-/*
- * io context count accounting
- */
-#define elv_ioc_count_mod(name, __val) this_cpu_add(name, __val)
-#define elv_ioc_count_inc(name)        this_cpu_inc(name)
-#define elv_ioc_count_dec(name)        this_cpu_dec(name)
-
-#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 /* CONFIG_BLOCK */
 #endif