From owner-freebsd-bugs@FreeBSD.ORG Fri Jul 11 06:10:01 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CBCD31065671 for ; Fri, 11 Jul 2008 06:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id AF80D8FC0C for ; Fri, 11 Jul 2008 06:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m6B6A10x085726 for ; Fri, 11 Jul 2008 06:10:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m6B6A1nC085725; Fri, 11 Jul 2008 06:10:01 GMT (envelope-from gnats) Resent-Date: Fri, 11 Jul 2008 06:10:01 GMT Resent-Message-Id: <200807110610.m6B6A1nC085725@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Andrey V. Elsukov" Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 966E7106567D for ; Fri, 11 Jul 2008 06:05:17 +0000 (UTC) (envelope-from root@butcher.heavennet.ru) Received: from insysnet.ru (ns.insysnet.ru [77.72.140.26]) by mx1.freebsd.org (Postfix) with SMTP id B96AB8FC1C for ; Fri, 11 Jul 2008 06:05:16 +0000 (UTC) (envelope-from root@butcher.heavennet.ru) Received: (qmail 86882 invoked from network); 11 Jul 2008 10:05:09 +0400 Received: from qmail by qscan (mail filter); 11 Jul 2008 06:05:09 +0000 Received: from unknown (HELO butcher.heavennet.ru) (77.72.136.194) by mail.insysnet.ru with SMTP; 11 Jul 2008 10:05:09 +0400 Received: by butcher.heavennet.ru (Postfix, from userid 0) id CC8434AC57; Fri, 11 Jul 2008 10:06:54 +0400 (MSD) Message-Id: <20080711060654.CC8434AC57@butcher.heavennet.ru> Date: Fri, 11 Jul 2008 10:06:54 +0400 (MSD) From: "Andrey V. Elsukov" To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: sos@FreeBSD.org Subject: kern/125496: [ata][patch] free memory on ataraid module unload X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: "Andrey V. Elsukov" List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jul 2008 06:10:01 -0000 >Number: 125496 >Category: kern >Synopsis: [ata][patch] free memory on ataraid module unload >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Jul 11 06:10:00 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Andrey V. Elsukov >Release: FreeBSD 6.2-STABLE i386 >Organization: >Environment: FreeBSD >Description: ataraid module has subdisk pseudo-driver which attaches to ata diskis. It calls ata_raid_read_metadata() function which allocate memory which shares between all subdisks in RAID: if (!raidp[array]) { raidp[array] = (struct ar_softc *)malloc(sizeof(struct ar_softc), M_AR, M_NOWAIT | M_ZERO); if (!raidp[array]) { device_printf(parent, "failed to allocate metadata storage\n"); goto adaptec_out; } } (Similar code has all ata_raid_xxxx_read_meta functions) Pointer to this memory stored in static local array ata_raid_arrays[]. This memory not freed when ataraid module unloads. Attached patch adds freeing memory on module unload. Because ataraid(4) module has two kernel modules - subdisk and ataraid, they both will be unloaded when `kldunload ataraid`. And all subdisks will be detached. So we can free shared memory between subdisks, but we should reset all pointers before freeing, because ata_raid_subdisk_detach() method will be called on module unload and this method can do access to this memory after freeing. I'm not 100% sure in correctness of this patch, so it needs review.. >How-To-Repeat: >Fix: --- ataraid_fix_memory_leak_on_module_unload.diff begins here --- Index: src/sys/dev/ata/ata-raid.c =================================================================== RCS file: /ncvs/src/sys/dev/ata/ata-raid.c,v retrieving revision 1.130 diff -u -b -p -r1.130 ata-raid.c --- src/sys/dev/ata/ata-raid.c 17 Apr 2008 12:29:35 -0000 1.130 +++ src/sys/dev/ata/ata-raid.c 10 Jul 2008 13:45:27 -0000 @@ -4205,7 +4205,9 @@ DRIVER_MODULE(subdisk, ad, ata_raid_sub_ static int ata_raid_module_event_handler(module_t mod, int what, void *arg) { - int i; + device_t subdisk; + struct ata_raid_subdisk *ars; + int i, disk; switch (what) { case MOD_LOAD: @@ -4244,6 +4246,13 @@ ata_raid_module_event_handler(module_t m mtx_destroy(&rdp->lock); if (rdp->disk) disk_destroy(rdp->disk); + for (disk = 0; disk < rdp->total_disks; disk++) { + subdisk = devclass_get_device(ata_raid_sub_devclass, + device_get_unit(rdp->disks[disk].dev)); + if (subdisk && (ars = device_get_softc(subdisk))) + ars->raid[rdp->volume] = NULL; + } + free(rdp, M_AR); } if (testing || bootverbose) printf("ATA PseudoRAID unloaded\n"); --- ataraid_fix_memory_leak_on_module_unload.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted: