diff options
author | Joe Thornber <ejt@redhat.com> | 2015-02-20 07:58:03 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2015-03-31 12:03:48 -0400 |
commit | 75da39bf256c27e25f395b191ead79f323772672 (patch) | |
tree | 8cd4fc26659bdef11314cab2aea3d8a61e290fc8 | |
parent | ac1f9ef211d5dd70110fa4bec6e8866b2c3a965e (diff) |
dm cache policy mq: keep track of the number of entries in a multiqueue
Small optimisation, now queue_empty() doesn't need to walk all levels of
the multiqueue.
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r-- | drivers/md/dm-cache-policy-mq.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/drivers/md/dm-cache-policy-mq.c b/drivers/md/dm-cache-policy-mq.c index 13f547a4eeb6..ca05d69191e8 100644 --- a/drivers/md/dm-cache-policy-mq.c +++ b/drivers/md/dm-cache-policy-mq.c | |||
@@ -126,6 +126,7 @@ static void iot_examine_bio(struct io_tracker *t, struct bio *bio) | |||
126 | #define NR_QUEUE_LEVELS 16u | 126 | #define NR_QUEUE_LEVELS 16u |
127 | 127 | ||
128 | struct queue { | 128 | struct queue { |
129 | unsigned nr_elts; | ||
129 | struct list_head qs[NR_QUEUE_LEVELS]; | 130 | struct list_head qs[NR_QUEUE_LEVELS]; |
130 | }; | 131 | }; |
131 | 132 | ||
@@ -133,23 +134,14 @@ static void queue_init(struct queue *q) | |||
133 | { | 134 | { |
134 | unsigned i; | 135 | unsigned i; |
135 | 136 | ||
137 | q->nr_elts = 0; | ||
136 | for (i = 0; i < NR_QUEUE_LEVELS; i++) | 138 | for (i = 0; i < NR_QUEUE_LEVELS; i++) |
137 | INIT_LIST_HEAD(q->qs + i); | 139 | INIT_LIST_HEAD(q->qs + i); |
138 | } | 140 | } |
139 | 141 | ||
140 | /* | ||
141 | * Checks to see if the queue is empty. | ||
142 | * FIXME: reduce cpu usage. | ||
143 | */ | ||
144 | static bool queue_empty(struct queue *q) | 142 | static bool queue_empty(struct queue *q) |
145 | { | 143 | { |
146 | unsigned i; | 144 | return q->nr_elts == 0; |
147 | |||
148 | for (i = 0; i < NR_QUEUE_LEVELS; i++) | ||
149 | if (!list_empty(q->qs + i)) | ||
150 | return false; | ||
151 | |||
152 | return true; | ||
153 | } | 145 | } |
154 | 146 | ||
155 | /* | 147 | /* |
@@ -157,11 +149,13 @@ static bool queue_empty(struct queue *q) | |||
157 | */ | 149 | */ |
158 | static void queue_push(struct queue *q, unsigned level, struct list_head *elt) | 150 | static void queue_push(struct queue *q, unsigned level, struct list_head *elt) |
159 | { | 151 | { |
152 | q->nr_elts++; | ||
160 | list_add_tail(elt, q->qs + level); | 153 | list_add_tail(elt, q->qs + level); |
161 | } | 154 | } |
162 | 155 | ||
163 | static void queue_remove(struct list_head *elt) | 156 | static void queue_remove(struct queue *q, struct list_head *elt) |
164 | { | 157 | { |
158 | q->nr_elts--; | ||
165 | list_del(elt); | 159 | list_del(elt); |
166 | } | 160 | } |
167 | 161 | ||
@@ -197,6 +191,7 @@ static struct list_head *queue_pop(struct queue *q) | |||
197 | struct list_head *r = queue_peek(q); | 191 | struct list_head *r = queue_peek(q); |
198 | 192 | ||
199 | if (r) { | 193 | if (r) { |
194 | q->nr_elts--; | ||
200 | list_del(r); | 195 | list_del(r); |
201 | 196 | ||
202 | /* have we just emptied the bottom level? */ | 197 | /* have we just emptied the bottom level? */ |
@@ -496,7 +491,11 @@ static void push(struct mq_policy *mq, struct entry *e) | |||
496 | */ | 491 | */ |
497 | static void del(struct mq_policy *mq, struct entry *e) | 492 | static void del(struct mq_policy *mq, struct entry *e) |
498 | { | 493 | { |
499 | queue_remove(&e->list); | 494 | if (in_cache(mq, e)) |
495 | queue_remove(e->dirty ? &mq->cache_dirty : &mq->cache_clean, &e->list); | ||
496 | else | ||
497 | queue_remove(&mq->pre_cache, &e->list); | ||
498 | |||
500 | hash_remove(e); | 499 | hash_remove(e); |
501 | } | 500 | } |
502 | 501 | ||