From root@butcher.heavennet.ru  Fri Jul 11 06:05:17 2008
Return-Path: <root@butcher.heavennet.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 966E7106567D
	for <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <bu7cher@yandex.ru>
Reply-To: Andrey V. Elsukov <bu7cher@yandex.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc: <sos@freebsd.org>
Subject: [ata][patch] free memory on ataraid module unload
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         125496
>Category:       kern
>Synopsis:       [ar] [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:  Thu Feb 19 22:25:09 UTC 2009
>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:

From: "Andrey V. Elsukov" <bu7cher@yandex.ru>
To: "Andrey V. Elsukov" <bu7cher@yandex.ru>
Cc: FreeBSD-gnats-submit@FreeBSD.org, sos@FreeBSD.org
Subject: Re: kern/125496: [ata][patch] free memory on ataraid module unload
Date: Fri, 11 Jul 2008 10:15:21 +0400

 Andrey V. Elsukov wrote:
 > I'm not 100% sure in correctness of this patch, so it needs review..
 
 I forgot to mention that it works for me. Without patch after unload
 module system reports that 1k ar_driver-type memory leaked. After
 patch this message gone. I have only one RAID configured on Intel
 Matrix.
 
 -- 
 WBR, Andrey V. Elsukov
>Unformatted:
