lkml.org 
[lkml]   [2004]   [Jul]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] cfq: bad allocation
Hi,

Arjan (sensibly) put a might_sleep() in mempool_alloc() and it caught a
bad cfq usage, pretty embarassaing actually. This patch should fix it
up.

Signed-off-by: Jens Axboe <axboe@suse.de>

--- /opt/kernel/linux-2.6.7-mm6/drivers/block/cfq-iosched.c 2004-07-07 10:33:29.000000000 +0200
+++ linux-2.6.7-mm6/drivers/block/cfq-iosched.c 2004-07-07 14:37:19.546229784 +0200
@@ -456,21 +456,23 @@
mempool_free(cfqq, cfq_mpool);
}

-static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, int pid)
+static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, int pid, int mask)
{
const int hashval = hash_long(current->tgid, CFQ_QHASH_SHIFT);
struct cfq_queue *cfqq = __cfq_find_cfq_hash(cfqd, pid, hashval);

if (!cfqq) {
- cfqq = mempool_alloc(cfq_mpool, GFP_NOIO);
+ cfqq = mempool_alloc(cfq_mpool, mask);

- INIT_LIST_HEAD(&cfqq->cfq_hash);
- INIT_LIST_HEAD(&cfqq->cfq_list);
- RB_CLEAR_ROOT(&cfqq->sort_list);
-
- cfqq->pid = pid;
- cfqq->queued[0] = cfqq->queued[1] = 0;
- list_add(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
+ if (cfqq) {
+ INIT_LIST_HEAD(&cfqq->cfq_hash);
+ INIT_LIST_HEAD(&cfqq->cfq_list);
+ RB_CLEAR_ROOT(&cfqq->sort_list);
+
+ cfqq->pid = pid;
+ cfqq->queued[0] = cfqq->queued[1] = 0;
+ list_add(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]);
+ }
}

return cfqq;
@@ -478,15 +480,22 @@

static void cfq_enqueue(struct cfq_data *cfqd, struct cfq_rq *crq)
{
- struct cfq_queue *cfqq;
-
- cfqq = cfq_get_queue(cfqd, current->tgid);
+ struct cfq_queue *cfqq = cfq_get_queue(cfqd, current->tgid, GFP_ATOMIC);

- cfq_add_crq_rb(cfqd, cfqq, crq);
+ if (cfqq) {
+ cfq_add_crq_rb(cfqd, cfqq, crq);

- if (list_empty(&cfqq->cfq_list)) {
- list_add(&cfqq->cfq_list, &cfqd->rr_list);
- cfqd->busy_queues++;
+ if (list_empty(&cfqq->cfq_list)) {
+ list_add(&cfqq->cfq_list, &cfqd->rr_list);
+ cfqd->busy_queues++;
+ }
+ } else {
+ /*
+ * should can only happen if the request wasn't allocated
+ * through blk_alloc_request(), eg stack requests from ide-cd
+ * (those should be removed) _and_ we are in OOM.
+ */
+ list_add_tail(&crq->request->queuelist, cfqd->dispatch);
}
}

@@ -617,8 +626,17 @@
static int cfq_set_request(request_queue_t *q, struct request *rq, int gfp_mask)
{
struct cfq_data *cfqd = q->elevator.elevator_data;
- struct cfq_rq *crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
+ struct cfq_queue *cfqq;
+ struct cfq_rq *crq;
+
+ /*
+ * prepare a queue up front, so cfq_enqueue() doesn't have to
+ */
+ cfqq = cfq_get_queue(cfqd, current->tgid, gfp_mask);
+ if (!cfqq)
+ return 1;

+ crq = mempool_alloc(cfqd->crq_pool, gfp_mask);
if (crq) {
RB_CLEAR(&crq->rb_node);
crq->request = rq;
--
Jens Axboe

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:04    [W:0.048 / U:0.468 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site