Commit 242d98f077ac0ab80920219769eb095503b93f61
Committed by
Jens Axboe
1 parent
9931faca02
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
block/blk.h
... | ... | @@ -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); |
block/elevator.c
... | ... | @@ -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 | /* |