Skip to content

Commit

Permalink
block,elevator: use new hashtable implementation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sasha Levin authored and Jens Axboe committed Jan 11, 2013
1 parent 9931fac commit 242d98f
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 21 deletions.
2 changes: 1 addition & 1 deletion block/blk.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static inline void blk_clear_rq_complete(struct request *rq)
/*
* Internal elevator interface
*/
#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash))
#define ELV_ON_HASH(rq) hash_hashed(&(rq)->hash)

void blk_insert_flush(struct request *rq);
void blk_abort_flushes(struct request_queue *q);
Expand Down
23 changes: 4 additions & 19 deletions block/elevator.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ static LIST_HEAD(elv_list);
/*
* Merge hash stuff.
*/
static const int elv_hash_shift = 6;
#define ELV_HASH_BLOCK(sec) ((sec) >> 3)
#define ELV_HASH_FN(sec) \
(hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift))
#define ELV_HASH_ENTRIES (1 << elv_hash_shift)
#define rq_hash_key(rq) (blk_rq_pos(rq) + blk_rq_sectors(rq))

/*
Expand Down Expand Up @@ -142,7 +137,6 @@ static struct elevator_queue *elevator_alloc(struct request_queue *q,
struct elevator_type *e)
{
struct elevator_queue *eq;
int i;

eq = kmalloc_node(sizeof(*eq), GFP_KERNEL | __GFP_ZERO, q->node);
if (unlikely(!eq))
Expand All @@ -151,14 +145,7 @@ static struct elevator_queue *elevator_alloc(struct request_queue *q,
eq->type = e;
kobject_init(&eq->kobj, &elv_ktype);
mutex_init(&eq->sysfs_lock);

eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
GFP_KERNEL, q->node);
if (!eq->hash)
goto err;

for (i = 0; i < ELV_HASH_ENTRIES; i++)
INIT_HLIST_HEAD(&eq->hash[i]);
hash_init(eq->hash);

return eq;
err:
Expand All @@ -173,7 +160,6 @@ static void elevator_release(struct kobject *kobj)

e = container_of(kobj, struct elevator_queue, kobj);
elevator_put(e->type);
kfree(e->hash);
kfree(e);
}

Expand Down Expand Up @@ -240,7 +226,7 @@ EXPORT_SYMBOL(elevator_exit);

static inline void __elv_rqhash_del(struct request *rq)
{
hlist_del_init(&rq->hash);
hash_del(&rq->hash);
}

static void elv_rqhash_del(struct request_queue *q, struct request *rq)
Expand All @@ -254,7 +240,7 @@ static void elv_rqhash_add(struct request_queue *q, struct request *rq)
struct elevator_queue *e = q->elevator;

BUG_ON(ELV_ON_HASH(rq));
hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]);
hash_add(e->hash, &rq->hash, rq_hash_key(rq));
}

static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
Expand All @@ -266,11 +252,10 @@ static void elv_rqhash_reposition(struct request_queue *q, struct request *rq)
static struct request *elv_rqhash_find(struct request_queue *q, sector_t offset)
{
struct elevator_queue *e = q->elevator;
struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)];
struct hlist_node *entry, *next;
struct request *rq;

hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) {
hash_for_each_possible_safe(e->hash, rq, entry, next, hash, offset) {
BUG_ON(!ELV_ON_HASH(rq));

if (unlikely(!rq_mergeable(rq))) {
Expand Down
5 changes: 4 additions & 1 deletion include/linux/elevator.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _LINUX_ELEVATOR_H

#include <linux/percpu.h>
#include <linux/hashtable.h>

#ifdef CONFIG_BLOCK

Expand Down Expand Up @@ -96,6 +97,8 @@ struct elevator_type
struct list_head list;
};

#define ELV_HASH_BITS 6

/*
* each queue has an elevator_queue associated with it
*/
Expand All @@ -105,8 +108,8 @@ struct elevator_queue
void *elevator_data;
struct kobject kobj;
struct mutex sysfs_lock;
struct hlist_head *hash;
unsigned int registered:1;
DECLARE_HASHTABLE(hash, ELV_HASH_BITS);
};

/*
Expand Down

0 comments on commit 242d98f

Please sign in to comment.