From: Nick Piggin Addition request debug to detect when we're leaking requests. drivers/block/as-iosched.c | 8 ++++++++ drivers/block/ll_rw_blk.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff -puN drivers/block/ll_rw_blk.c~io-refcount-debugging drivers/block/ll_rw_blk.c --- 25/drivers/block/ll_rw_blk.c~io-refcount-debugging 2003-10-02 02:27:35.000000000 -0700 +++ 25-akpm/drivers/block/ll_rw_blk.c 2003-10-02 02:28:19.000000000 -0700 @@ -1465,6 +1465,8 @@ static void freed_request(request_queue_ } } +atomic_t global_nr_requests = ATOMIC_INIT(0); + #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) /* * Get a free request, queue_lock must not be held @@ -1542,6 +1544,8 @@ static struct request *get_request(reque rq->data = NULL; rq->sense = NULL; + atomic_inc(&global_nr_requests); + out: put_io_context(ioc); return rq; @@ -1772,6 +1776,9 @@ void __blk_put_request(request_queue_t * blk_free_request(q, req); freed_request(q, rw); + + WARN_ON(atomic_read(&global_nr_requests) == 0); + atomic_dec(&global_nr_requests); } } @@ -2582,6 +2589,8 @@ int __init blk_dev_init(void) return 0; } +static atomic_t nr_io_contexts = ATOMIC_INIT(0); + /* * IO Context helper functions */ @@ -2596,6 +2605,8 @@ void put_io_context(struct io_context *i if (ioc->aic && ioc->aic->dtor) ioc->aic->dtor(ioc->aic); kfree(ioc); + WARN_ON(atomic_read(&nr_io_contexts) == 0); + atomic_dec(&nr_io_contexts); } } @@ -2636,6 +2647,10 @@ struct io_context *get_io_context(int gf if (ret == NULL) { ret = kmalloc(sizeof(*ret), GFP_ATOMIC); if (ret) { + atomic_inc(&nr_io_contexts); + WARN_ON(atomic_read(&nr_io_contexts) == + 1 + nr_threads + atomic_read(&global_nr_requests)); + atomic_set(&ret->refcount, 1); ret->pid = tsk->pid; ret->last_waited = jiffies; /* doesn't matter... */ diff -puN drivers/block/as-iosched.c~io-refcount-debugging drivers/block/as-iosched.c --- 25/drivers/block/as-iosched.c~io-refcount-debugging 2003-10-02 02:27:35.000000000 -0700 +++ 25-akpm/drivers/block/as-iosched.c 2003-10-02 02:28:19.000000000 -0700 @@ -173,10 +173,15 @@ static kmem_cache_t *arq_pool; /* * IO Context helper functions */ +/* Debug */ +extern atomic_t global_nr_requests; +static atomic_t nr_as_io_contexts = ATOMIC_INIT(0); /* Called to deallocate the as_io_context */ static void free_as_io_context(struct as_io_context *aic) { + WARN_ON(atomic_read(&nr_as_io_contexts) == 0); + atomic_dec(&nr_as_io_contexts); kfree(aic); } @@ -192,6 +197,9 @@ static struct as_io_context *alloc_as_io ret = kmalloc(sizeof(*ret), GFP_ATOMIC); if (ret) { + atomic_inc(&nr_as_io_contexts); + WARN_ON(atomic_read(&nr_as_io_contexts) == + 1 + nr_threads + atomic_read(&global_nr_requests)); ret->dtor = free_as_io_context; ret->exit = exit_as_io_context; ret->state = 1 << AS_TASK_RUNNING; _