kern/125496: [ata][patch] free memory on ataraid module unload
Andrey V. Elsukov
bu7cher at yandex.ru
Fri Jul 11 06:10:01 UTC 2008
>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:
More information about the freebsd-bugs
mailing list