Re: [3.1-rc6] kmalloc(64) leak from IDE

From: Borislav Petkov
Date: Thu Sep 22 2011 - 04:48:18 EST


On Thu, Sep 22, 2011 at 12:26:44AM -0700, Simon Kirby wrote:
> All sorts of fun with 3.1-rc!
>
> On an older x86 box still using the IDE code, I'm seeing a kmalloc(64)
> leak (according to slabtop) that basically OOM'd the box in a few days
> (640 MB of RAM). This has popped up since 2.6.36, which ran for a long
> time on this box with no problems. Issues seen on -rc5, so I rebuilt with
> CONFIG_DEBUG_KMEMLEAK on 9d037a777695993ec7437e5f451647dea7919d4c and
> /sys/kernel/debug/kmemleak filled up with size 64 traces involving IDE
> requests. Every trace seems to contain idedisk_prep_fn():
>
> unreferenced object 0xe30c00c0 (size 64):
> comm "md6_raid1", pid 255, jiffies 4294903935 (age 23889.704s)
> hex dump (first 32 bytes):
> 00 00 00 00 00 00 00 ea 00 00 00 00 00 00 00 00 ................
> 7e 00 00 00 20 00 00 00 01 00 00 00 00 00 00 00 ~... ...........
> backtrace:
> [<c1495c37>] kmemleak_alloc+0x27/0x50
> [<c10b2f4a>] kmem_cache_alloc_trace+0x8a/0x120
> [<c131fe47>] idedisk_prep_fn+0x37/0xf0
> [<c12758b3>] blk_peek_request+0xa3/0x1e0
> [<c1311f15>] __ide_requeue_and_plug+0x25/0x30
> [<c131257d>] do_ide_request+0x3d/0x4e0
> [<c1270ff4>] __blk_run_queue+0x14/0x20
> [<c127699c>] __make_request+0x21c/0x290
> [<c1274f26>] generic_make_request+0x1a6/0x490
> [<c127526c>] submit_bio+0x5c/0xd0
> [<c13a651b>] md_super_write+0x6b/0x80
> [<c13a67ec>] md_update_sb+0x2bc/0x540
> [<c13a7d51>] md_check_recovery+0x2c1/0x5f0
> [<c138abce>] raid1d+0x2e/0xd90
> [<c13a58d5>] md_thread+0xe5/0x110
> [<c1047df4>] kthread+0x74/0x80
>
> unreferenced object 0xc1c3d900 (size 64):
> comm "hardirq", pid 0, jiffies 5819438 (age 829.636s)
> hex dump (first 32 bytes):
> 00 00 00 00 00 00 00 ea 00 00 00 00 00 00 00 00 ................
> 7e 00 00 00 20 00 00 00 01 00 00 00 00 00 00 00 ~... ...........
> backtrace:
> [<c1495c37>] kmemleak_alloc+0x27/0x50
> [<c10b2f4a>] kmem_cache_alloc_trace+0x8a/0x120
> [<c131fe47>] idedisk_prep_fn+0x37/0xf0
> [<c12758b3>] blk_peek_request+0xa3/0x1e0
> [<c1311f15>] __ide_requeue_and_plug+0x25/0x30
> [<c1311f2f>] ide_requeue_and_plug+0xf/0x20
> [<c1311fb8>] ide_intr+0x78/0x1e0
> [<c1065c14>] handle_irq_event_percpu+0x54/0x1d0
> [<c1065dac>] handle_irq_event+0x1c/0x30
> [<c1067b8c>] handle_level_irq+0x4c/0xa0
> [<ffffffff>] 0xffffffff
>
> idedisk_prep_fn() seems to allocate a command and return it as
> rq->special, but I'm not following what happens after that.

AFAIR, that's blk_peek_request - it calls q->prep_rq_fn which is
idedisk_prep_fn() and it unconditionally allocates those ide_cmd's
without freeing them and I can imagine the upper layer requeue one
request a couple of times back-to-back, leading to the leaks.

So maybe the following could work, it is a stab in the dark for all I
know:

--
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 274798068a54..16f69be820c7 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -435,7 +435,12 @@ static int idedisk_prep_fn(struct request_queue *q, struct request *rq)
if (!(rq->cmd_flags & REQ_FLUSH))
return BLKPREP_OK;

- cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+ if (rq->special) {
+ cmd = rq->special;
+ memset(cmd, 0, sizeof(*cmd));
+ } else {
+ cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+ }

/* FIXME: map struct ide_taskfile on rq->cmd[] */
BUG_ON(cmd == NULL);
--

Can you rerun it with kmemleak enabled and check whether it still
triggers?

Also, I'm sure you know IDE is deprecated, so what are the chances of
moving this box to libata? Also, can you send me your .config pls?

Thanks.

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