Commit 242d98f077ac0ab80920219769eb095503b93f61

Authored by Sasha Levin
Committed by Jens Axboe
1 parent 9931faca02

block,elevator: use new hashtable implementation

Switch elevator to use the new hashtable implementation. This reduces the
amount of generic unrelated code in the elevator.

This also removes the dymanic allocation of the hash table. The size of the table is
constant so there's no point in paying the price of an extra dereference when accessing
it.

This patch depends on d9b482c ("hashtable: introduce a small and naive
hashtable") which was merged in v3.6.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

Showing 3 changed files with 9 additions and 21 deletions Side-by-side Diff

... ... @@ -61,7 +61,7 @@
61 61 /*
62 62 * Internal elevator interface
63 63 */
64   -#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
  64 +#define ELV_ON_HASH(rq) hash_hashed(&(rq)->hash)
65 65  
66 66 void blk_insert_flush(struct request *rq);
67 67 void blk_abort_flushes(struct request_queue *q);
... ... @@ -46,11 +46,6 @@
46 46 /*
47 47 * Merge hash stuff.
48 48 */
49   -static const int elv_hash_shift = 6;
50   -#define ELV_HASH_BLOCK(sec) ((sec) >> 3)
51   -#define ELV_HASH_FN(sec) \
52   - (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift))
53   -#define ELV_HASH_ENTRIES (1 << elv_hash_shift)
54 49 #define rq_hash_key(rq) (blk_rq_pos(rq) + blk_rq_sectors(rq))
55 50  
56 51 /*
... ... @@ -142,7 +137,6 @@
142 137 struct elevator_type *e)
143 138 {
144 139 struct elevator_queue *eq;
145   - int i;
146 140  
147 141 eq = kmalloc_node(sizeof(*eq), GFP_KERNEL | __GFP_ZERO, q->node);
148 142 if (unlikely(!eq))
149 143  
... ... @@ -151,15 +145,8 @@
151 145 eq->type = e;
152 146 kobject_init(&eq->kobj, &elv_ktype);
153 147 mutex_init(&eq->sysfs_lock);
  148 + hash_init(eq->hash);
154 149  
155   - eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
156   - GFP_KERNEL, q->node);
157   - if (!eq->hash)
158   - goto err;
159   -
160   - for (i = 0; i < ELV_HASH_ENTRIES; i++)
161   - INIT_HLIST_HEAD(&eq->hash[i]);
162   -
163 150 return eq;
164 151 err:
165 152 kfree(eq);
... ... @@ -173,7 +160,6 @@
173 160  
174 161 e = container_of(kobj, struct elevator_queue, kobj);
175 162 elevator_put(e->type);
176   - kfree(e->hash);
177 163 kfree(e);
178 164 }
179 165  
... ... @@ -240,7 +226,7 @@
240 226  
241 227 static inline void __elv_rqhash_del(struct request *rq)
242 228 {
243   - hlist_del_init(&rq->hash);
  229 + hash_del(&rq->hash);
244 230 }
245 231  
246 232 static void elv_rqhash_del(struct request_queue *q, struct request *rq)
... ... @@ -254,7 +240,7 @@
254 240 struct elevator_queue *e = q->elevator;
255 241  
256 242 BUG_ON(ELV_ON_HASH(rq));
257   - hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]);
  243 + hash_add(e->hash, &rq->hash, rq_hash_key(rq));
258 244 }
259 245  
260 246 static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
261 247  
... ... @@ -266,11 +252,10 @@
266 252 static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
267 253 {
268 254 struct elevator_queue *e = q->elevator;
269   - struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)];
270 255 struct hlist_node *entry, *next;
271 256 struct request *rq;
272 257  
273   - hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) {
  258 + hash_for_each_possible_safe(e->hash, rq, entry, next, hash, offset) {
274 259 BUG_ON(!ELV_ON_HASH(rq));
275 260  
276 261 if (unlikely(!rq_mergeable(rq))) {
include/linux/elevator.h
... ... @@ -2,6 +2,7 @@
2 2 #define _LINUX_ELEVATOR_H
3 3  
4 4 #include <linux/percpu.h>
  5 +#include <linux/hashtable.h>
5 6  
6 7 #ifdef CONFIG_BLOCK
7 8  
... ... @@ -96,6 +97,8 @@
96 97 struct list_head list;
97 98 };
98 99  
  100 +#define ELV_HASH_BITS 6
  101 +
99 102 /*
100 103 * each queue has an elevator_queue associated with it
101 104 */
102 105  
... ... @@ -105,8 +108,8 @@
105 108 void *elevator_data;
106 109 struct kobject kobj;
107 110 struct mutex sysfs_lock;
108   - struct hlist_head *hash;
109 111 unsigned int registered:1;
  112 + DECLARE_HASHTABLE(hash, ELV_HASH_BITS);
110 113 };
111 114  
112 115 /*