Date: Fri, 1 Apr 2011 19:43:54 +0200 From: Victor Balada Diaz <victor@bsdes.net> To: stable@freebsd.org Subject: Re: geli(4) memory leak Message-ID: <20110401174354.GE1289@equilibrium.bsdes.net> In-Reply-To: <20110326003348.GQ36706@equilibrium.bsdes.net> References: <20110326003348.GQ36706@equilibrium.bsdes.net>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Sat, Mar 26, 2011 at 01:33:48AM +0100, Victor Balada Diaz wrote:
> Hello,
>
> I'm trying to setup a new geli disk and i'm seeing what looks like a memory leak.
> After initializing the device i've tried to do the dd command from /dev/random
> like this one:
>
> dd if=/dev/random of=/dev/da0p1.eli bs=1m
>
Hello again,
I've found the cause of the memory leak and i attach a patch to fix it. I hope
the patch is good enough to get committed or at least helps someone made a better
patch and commit it. Patched file is src/sys/geom/eli/g_eli.c
The problem happens when you're using data integrity verification and you need
to write more than MAXPHYS. If you look at g_eli_integrity.c:314 you'll
see that geli creates a second request to write all that's needed.
Each of the request get the callback to g_eli_write_done once they're done. The
first request will get up to g_eli.c:209 and find that there are still requests
pending so instead of calling g_io_deliver to notify it's written data, it just
returns and waits until all requests are done to say everything's OK. The problem
is that once you return, you're leaking this g_bio. You can see with vmstat -z how
g_bio increases and never releases memory.
I just destroy the current bio before returning and that prevents the memory leak.
Regards.
Victor.
--
La prueba más fehaciente de que existe vida inteligente en otros
planetas, es que no han intentado contactar con nosotros.
[-- Attachment #2 --]
--- g_eli.c 2010-12-21 18:09:25.000000000 +0100
+++ g_eli.c.patched 2011-04-01 19:16:41.000000000 +0200
@@ -206,8 +206,10 @@
* Do we have all sectors already?
*/
pbp->bio_inbed++;
- if (pbp->bio_inbed < pbp->bio_children)
+ if (pbp->bio_inbed < pbp->bio_children) {
+ g_destroy_bio(bp);
return;
+ }
free(pbp->bio_driver2, M_ELI);
pbp->bio_driver2 = NULL;
if (pbp->bio_error != 0) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110401174354.GE1289>
