[PATCH] xfs: fix memory leak in xfs_iext_free_last_leaf

2017-11-20 Thread shuwang
From: Shu Wang 

found the issue by kmemleak.
unreferenced object 0x8800674611c0 (size 16):
xfs_iext_insert+0x82a/0xa90 [xfs]
xfs_bmap_add_extent_hole_delay+0x1e5/0x5b0 [xfs]
xfs_bmapi_reserve_delalloc+0x483/0x530 [xfs]
xfs_file_iomap_begin+0xac8/0xd40 [xfs]
iomap_apply+0xb8/0x1b0
iomap_file_buffered_write+0xac/0xe0
xfs_file_buffered_aio_write+0x198/0x420 [xfs]
xfs_file_write_iter+0x23f/0x2a0 [xfs]
__vfs_write+0x23e/0x340
vfs_write+0xe9/0x240
SyS_write+0xa1/0x120
do_syscall_64+0xda/0x260

Signed-off-by: Shu Wang 
---
 fs/xfs/libxfs/xfs_iext_tree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_iext_tree.c b/fs/xfs/libxfs/xfs_iext_tree.c
index 19e546a41251..89bf16b4d937 100644
--- a/fs/xfs/libxfs/xfs_iext_tree.c
+++ b/fs/xfs/libxfs/xfs_iext_tree.c
@@ -850,9 +850,9 @@ static void
 xfs_iext_free_last_leaf(
struct xfs_ifork*ifp)
 {
-   ifp->if_u1.if_root = NULL;
ifp->if_height--;
kmem_free(ifp->if_u1.if_root);
+   ifp->if_u1.if_root = NULL;
 }
 
 void
-- 
2.13.5



[PATCH] xfs: fix memory leak in xfs_iext_free_last_leaf

2017-11-20 Thread shuwang
From: Shu Wang 

found the issue by kmemleak.
unreferenced object 0x8800674611c0 (size 16):
xfs_iext_insert+0x82a/0xa90 [xfs]
xfs_bmap_add_extent_hole_delay+0x1e5/0x5b0 [xfs]
xfs_bmapi_reserve_delalloc+0x483/0x530 [xfs]
xfs_file_iomap_begin+0xac8/0xd40 [xfs]
iomap_apply+0xb8/0x1b0
iomap_file_buffered_write+0xac/0xe0
xfs_file_buffered_aio_write+0x198/0x420 [xfs]
xfs_file_write_iter+0x23f/0x2a0 [xfs]
__vfs_write+0x23e/0x340
vfs_write+0xe9/0x240
SyS_write+0xa1/0x120
do_syscall_64+0xda/0x260

Signed-off-by: Shu Wang 
---
 fs/xfs/libxfs/xfs_iext_tree.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_iext_tree.c b/fs/xfs/libxfs/xfs_iext_tree.c
index 19e546a41251..89bf16b4d937 100644
--- a/fs/xfs/libxfs/xfs_iext_tree.c
+++ b/fs/xfs/libxfs/xfs_iext_tree.c
@@ -850,9 +850,9 @@ static void
 xfs_iext_free_last_leaf(
struct xfs_ifork*ifp)
 {
-   ifp->if_u1.if_root = NULL;
ifp->if_height--;
kmem_free(ifp->if_u1.if_root);
+   ifp->if_u1.if_root = NULL;
 }
 
 void
-- 
2.13.5



[PATCH] SMB: fix memory leak in smb3_validate_negotiate

2017-10-20 Thread shuwang
From: Shu Wang 

Found the issue by kmemleak. The pointer pneg_rsp stores the
pointer kmalloced from SMB2_ioctl, and should be release
before function return.

unreferenced object 0x88018c2b1900 (size 32):
  backtrace:
kmemleak_alloc+0x4a/0xa0
__kmalloc+0xec/0x220
SMB2_ioctl+0x27a/0x3c0 [cifs]
smb3_validate_negotiate+0x135/0x370 [cifs]
SMB2_tcon+0x308/0xae0 [cifs]
cifs_put_tcp_session+0x4a5/0x900 [cifs]
cifs_mount+0x6f4/0x15f0 [cifs]

Signed-off-by: Shu Wang 
---
 fs/cifs/smb2pdu.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 6f0e6343c15e..4785ed8e1589 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -727,8 +727,10 @@ int smb3_validate_negotiate(const unsigned int xid, struct 
cifs_tcon *tcon)
 rsplen);
 
/* relax check since Mac returns max bufsize allowed on ioctl */
-   if (rsplen > CIFSMaxBufSize)
+   if (rsplen > CIFSMaxBufSize) {
+   kfree(pneg_rsp);
return -EIO;
+   }
}
 
/* check validate negotiate info response matches what we got earlier */
@@ -747,10 +749,12 @@ int smb3_validate_negotiate(const unsigned int xid, 
struct cifs_tcon *tcon)
 
/* validate negotiate successful */
cifs_dbg(FYI, "validate negotiate info successful\n");
+   kfree(pneg_rsp);
return 0;
 
 vneg_out:
cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
+   kfree(pneg_rsp);
return -EIO;
 }
 
-- 
2.13.5



[PATCH] SMB: fix memory leak in smb3_validate_negotiate

2017-10-20 Thread shuwang
From: Shu Wang 

Found the issue by kmemleak. The pointer pneg_rsp stores the
pointer kmalloced from SMB2_ioctl, and should be release
before function return.

unreferenced object 0x88018c2b1900 (size 32):
  backtrace:
kmemleak_alloc+0x4a/0xa0
__kmalloc+0xec/0x220
SMB2_ioctl+0x27a/0x3c0 [cifs]
smb3_validate_negotiate+0x135/0x370 [cifs]
SMB2_tcon+0x308/0xae0 [cifs]
cifs_put_tcp_session+0x4a5/0x900 [cifs]
cifs_mount+0x6f4/0x15f0 [cifs]

Signed-off-by: Shu Wang 
---
 fs/cifs/smb2pdu.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 6f0e6343c15e..4785ed8e1589 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -727,8 +727,10 @@ int smb3_validate_negotiate(const unsigned int xid, struct 
cifs_tcon *tcon)
 rsplen);
 
/* relax check since Mac returns max bufsize allowed on ioctl */
-   if (rsplen > CIFSMaxBufSize)
+   if (rsplen > CIFSMaxBufSize) {
+   kfree(pneg_rsp);
return -EIO;
+   }
}
 
/* check validate negotiate info response matches what we got earlier */
@@ -747,10 +749,12 @@ int smb3_validate_negotiate(const unsigned int xid, 
struct cifs_tcon *tcon)
 
/* validate negotiate successful */
cifs_dbg(FYI, "validate negotiate info successful\n");
+   kfree(pneg_rsp);
return 0;
 
 vneg_out:
cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
+   kfree(pneg_rsp);
return -EIO;
 }
 
-- 
2.13.5



[PATCH] hwmon: (coretemp) remove duplicated coretemp for same core id

2017-10-17 Thread shuwang
From: Shu Wang 

Fix kernel warning on my 4cpus 2core_id system. The cpu0 and cpu1 have
same core_id 0, so both cpu0 and cpu1 will try to create file temp2_label
when it's online.

- coretemp_cpu_online(cpu=0)
  - create_core_data(cpu=0, attr_no=2)
   - create_core_attrs(attr_no=2)
- coretemp_cpu_online(cpu=1)
  - create_core_data(cpu=1, attr_no=2)
   - create_core_attrs(attr_no=2)

$ grep -e processor -e 'core id' /proc/cpuinfo
processor   : 0
core id : 0
processor   : 1
core id : 0
processor   : 2
core id : 1
processor   : 3
core id : 1

dmesg:
sysfs: cannot create duplicate filename 
'/devices/platform/coretemp.0/hwmon/hwmon3/temp2_label'
sysfs: cannot create duplicate filename 
'/devices/platform/coretemp.0/hwmon/hwmon3/temp3_label'
WARNING: CPU: 3 PID: 27 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x58/0x70
Call Trace:
 sysfs_add_file_mode_ns+0x170/0x180
 internal_create_group+0xe3/0x2c0
 sysfs_create_group+0x13/0x20
 create_core_data+0x3ab/0x5e0 [coretemp]
 coretemp_cpu_online+0x14b/0x1f7 [coretemp]
 ? create_core_data+0x5e0/0x5e0 [coretemp]
 cpuhp_invoke_callback+0xae/0x5c0
 ? __schedule+0x295/0x880
 cpuhp_thread_fun+0xcb/0x170
 smpboot_thread_fn+0x110/0x160

Signed-off-by: Shu Wang 
---
 drivers/hwmon/coretemp.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index c13a4fd86b3c..2fb29ab1080b 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -459,6 +459,17 @@ static struct temp_data *init_temp_data(unsigned int cpu, 
int pkg_flag)
return tdata;
 }
 
+static void coretemp_remove_core(struct platform_data *pdata, int indx)
+{
+   struct temp_data *tdata = pdata->core_data[indx];
+
+   /* Remove the sysfs attributes */
+   sysfs_remove_group(>hwmon_dev->kobj, >attr_group);
+
+   kfree(pdata->core_data[indx]);
+   pdata->core_data[indx] = NULL;
+}
+
 static int create_core_data(struct platform_device *pdev, unsigned int cpu,
int pkg_flag)
 {
@@ -479,6 +490,10 @@ static int create_core_data(struct platform_device *pdev, 
unsigned int cpu,
if (attr_no > MAX_CORE_DATA - 1)
return -ERANGE;
 
+   tdata = pdata->core_data[attr_no];
+   if (tdata != NULL)
+   coretemp_remove_core(pdata, attr_no);
+
tdata = init_temp_data(cpu, pkg_flag);
if (!tdata)
return -ENOMEM;
@@ -527,17 +542,6 @@ coretemp_add_core(struct platform_device *pdev, unsigned 
int cpu, int pkg_flag)
dev_err(>dev, "Adding Core %u failed\n", cpu);
 }
 
-static void coretemp_remove_core(struct platform_data *pdata, int indx)
-{
-   struct temp_data *tdata = pdata->core_data[indx];
-
-   /* Remove the sysfs attributes */
-   sysfs_remove_group(>hwmon_dev->kobj, >attr_group);
-
-   kfree(pdata->core_data[indx]);
-   pdata->core_data[indx] = NULL;
-}
-
 static int coretemp_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
-- 
2.13.5



[PATCH] hwmon: (coretemp) remove duplicated coretemp for same core id

2017-10-17 Thread shuwang
From: Shu Wang 

Fix kernel warning on my 4cpus 2core_id system. The cpu0 and cpu1 have
same core_id 0, so both cpu0 and cpu1 will try to create file temp2_label
when it's online.

- coretemp_cpu_online(cpu=0)
  - create_core_data(cpu=0, attr_no=2)
   - create_core_attrs(attr_no=2)
- coretemp_cpu_online(cpu=1)
  - create_core_data(cpu=1, attr_no=2)
   - create_core_attrs(attr_no=2)

$ grep -e processor -e 'core id' /proc/cpuinfo
processor   : 0
core id : 0
processor   : 1
core id : 0
processor   : 2
core id : 1
processor   : 3
core id : 1

dmesg:
sysfs: cannot create duplicate filename 
'/devices/platform/coretemp.0/hwmon/hwmon3/temp2_label'
sysfs: cannot create duplicate filename 
'/devices/platform/coretemp.0/hwmon/hwmon3/temp3_label'
WARNING: CPU: 3 PID: 27 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x58/0x70
Call Trace:
 sysfs_add_file_mode_ns+0x170/0x180
 internal_create_group+0xe3/0x2c0
 sysfs_create_group+0x13/0x20
 create_core_data+0x3ab/0x5e0 [coretemp]
 coretemp_cpu_online+0x14b/0x1f7 [coretemp]
 ? create_core_data+0x5e0/0x5e0 [coretemp]
 cpuhp_invoke_callback+0xae/0x5c0
 ? __schedule+0x295/0x880
 cpuhp_thread_fun+0xcb/0x170
 smpboot_thread_fn+0x110/0x160

Signed-off-by: Shu Wang 
---
 drivers/hwmon/coretemp.c | 26 +++---
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index c13a4fd86b3c..2fb29ab1080b 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -459,6 +459,17 @@ static struct temp_data *init_temp_data(unsigned int cpu, 
int pkg_flag)
return tdata;
 }
 
+static void coretemp_remove_core(struct platform_data *pdata, int indx)
+{
+   struct temp_data *tdata = pdata->core_data[indx];
+
+   /* Remove the sysfs attributes */
+   sysfs_remove_group(>hwmon_dev->kobj, >attr_group);
+
+   kfree(pdata->core_data[indx]);
+   pdata->core_data[indx] = NULL;
+}
+
 static int create_core_data(struct platform_device *pdev, unsigned int cpu,
int pkg_flag)
 {
@@ -479,6 +490,10 @@ static int create_core_data(struct platform_device *pdev, 
unsigned int cpu,
if (attr_no > MAX_CORE_DATA - 1)
return -ERANGE;
 
+   tdata = pdata->core_data[attr_no];
+   if (tdata != NULL)
+   coretemp_remove_core(pdata, attr_no);
+
tdata = init_temp_data(cpu, pkg_flag);
if (!tdata)
return -ENOMEM;
@@ -527,17 +542,6 @@ coretemp_add_core(struct platform_device *pdev, unsigned 
int cpu, int pkg_flag)
dev_err(>dev, "Adding Core %u failed\n", cpu);
 }
 
-static void coretemp_remove_core(struct platform_data *pdata, int indx)
-{
-   struct temp_data *tdata = pdata->core_data[indx];
-
-   /* Remove the sysfs attributes */
-   sysfs_remove_group(>hwmon_dev->kobj, >attr_group);
-
-   kfree(pdata->core_data[indx]);
-   pdata->core_data[indx] = NULL;
-}
-
 static int coretemp_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
-- 
2.13.5



[PATCH] mm: kmemleak: start address align for scan_large_block

2017-10-11 Thread shuwang
From: Shu Wang 

If the start address is not ptr bytes aligned, it may cause false
positives when a pointer is split by MAX_SCAN_SIZE.

For example:
tcp_metrics_nl_family is in __ro_after_init area. On my PC, the
__start_ro_after_init is not ptr aligned, and
tcp_metrics_nl_family->attrbuf was break by MAX_SCAN_SIZE.

 # cat /proc/kallsyms | grep __start_ro_after_init
 81afac8b R __start_ro_after_init

 (gdb) p _metrics_nl_family->attrbuf
   (struct nlattr ***) 0x81b12c88 

 (gdb) p tcp_metrics_nl_family->attrbuf
   (struct nlattr **) 0x88007b9d9400

 scan_block(_start=0x81b11c8b, _end=0x81b12c8b, 0)
 scan_block(_start=0x81b12c8b, _end=0x81b13c8b, 0)

unreferenced object 0x88007b9d9400 (size 128):
  backtrace:
kmemleak_alloc+0x4a/0xa0
__kmalloc+0xec/0x220
genl_register_family.part.8+0x11c/0x5c0
genl_register_family+0x6f/0x90
tcp_metrics_init+0x33/0x47
tcp_init+0x27a/0x293
inet_init+0x176/0x28a
do_one_initcall+0x51/0x1b0

Signed-off-by: Shu Wang 
---
 mm/kmemleak.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd83a495..388b73e01fa4 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1376,6 +1376,7 @@ static void scan_block(void *_start, void *_end,
 static void scan_large_block(void *start, void *end)
 {
void *next;
+   start = PTR_ALIGN(start, BYTES_PER_POINTER);
 
while (start < end) {
next = min(start + MAX_SCAN_SIZE, end);
-- 
2.13.5



[PATCH] mm: kmemleak: start address align for scan_large_block

2017-10-11 Thread shuwang
From: Shu Wang 

If the start address is not ptr bytes aligned, it may cause false
positives when a pointer is split by MAX_SCAN_SIZE.

For example:
tcp_metrics_nl_family is in __ro_after_init area. On my PC, the
__start_ro_after_init is not ptr aligned, and
tcp_metrics_nl_family->attrbuf was break by MAX_SCAN_SIZE.

 # cat /proc/kallsyms | grep __start_ro_after_init
 81afac8b R __start_ro_after_init

 (gdb) p _metrics_nl_family->attrbuf
   (struct nlattr ***) 0x81b12c88 

 (gdb) p tcp_metrics_nl_family->attrbuf
   (struct nlattr **) 0x88007b9d9400

 scan_block(_start=0x81b11c8b, _end=0x81b12c8b, 0)
 scan_block(_start=0x81b12c8b, _end=0x81b13c8b, 0)

unreferenced object 0x88007b9d9400 (size 128):
  backtrace:
kmemleak_alloc+0x4a/0xa0
__kmalloc+0xec/0x220
genl_register_family.part.8+0x11c/0x5c0
genl_register_family+0x6f/0x90
tcp_metrics_init+0x33/0x47
tcp_init+0x27a/0x293
inet_init+0x176/0x28a
do_one_initcall+0x51/0x1b0

Signed-off-by: Shu Wang 
---
 mm/kmemleak.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd83a495..388b73e01fa4 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1376,6 +1376,7 @@ static void scan_block(void *_start, void *_end,
 static void scan_large_block(void *start, void *end)
 {
void *next;
+   start = PTR_ALIGN(start, BYTES_PER_POINTER);
 
while (start < end) {
next = min(start + MAX_SCAN_SIZE, end);
-- 
2.13.5



[PATCH] cgroup: cpuset: fix panic when offline a cpu

2017-09-22 Thread shuwang
From: Shu Wang 

cgroup_migrate assumes mgctx tset.csets is pointing to
tset.src_csets at start, add tasks to tset.src_csets in
func cgroup_migrate_add_task, change test.csets to
tset.dst_csets in cgroup_migrate_execute.

For offline a cpu in cgroup_transfer_tasks, it will first
migrate a task and cause tset.csets pointing to dst_csets.
Get a NULL pointer in cgroup_taskset_first.

reproducer on my 2 cpus machine:
mkdir /sys/fs/cgroup/cpuset/test
cd /sys/fs/cgroup/cpuset/test
echo 1 > cpuset.cpus
echo 0 > cpuset.mems
sleep 100 & echo $! > tasks
sleep 100 & echo $! > tasks
echo 0 > /sys/bus/cpu/devices/cpu1/online

backtrace:
BUG: unable to handle kernel NULL pointer dereference at 0cf8
IP: cpuset_can_attach+0x2f/0x140
Call Trace:
 ? cpuset_attach+0x30f/0x3d0
 cgroup_migrate_execute+0x71/0x3c0
 cgroup_migrate+0x75/0x80
 cgroup_transfer_tasks+0x1b2/0x230
 cpuset_hotplug_workfn+0xa7d/0xce0
 ? finish_task_switch+0x79/0x240
 process_one_work+0x149/0x360
 worker_thread+0x4d/0x3c0

Signed-off-by: Shu Wang 
---
 kernel/cgroup/cgroup-v1.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c
index 024085daab1a..165734573b5e 100644
--- a/kernel/cgroup/cgroup-v1.c
+++ b/kernel/cgroup/cgroup-v1.c
@@ -129,6 +129,12 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup 
*from)
css_task_iter_end();
 
if (task) {
+   /*
+* Reset csets to src_cets, as cgroup_migrate assumes
+* csets is pointing to src_csets.
+*/
+   mgctx.tset.csets = _csets;
+
ret = cgroup_migrate(task, false, );
if (!ret)
trace_cgroup_transfer_tasks(to, task, false);
-- 
2.13.5



[PATCH] cgroup: cpuset: fix panic when offline a cpu

2017-09-22 Thread shuwang
From: Shu Wang 

cgroup_migrate assumes mgctx tset.csets is pointing to
tset.src_csets at start, add tasks to tset.src_csets in
func cgroup_migrate_add_task, change test.csets to
tset.dst_csets in cgroup_migrate_execute.

For offline a cpu in cgroup_transfer_tasks, it will first
migrate a task and cause tset.csets pointing to dst_csets.
Get a NULL pointer in cgroup_taskset_first.

reproducer on my 2 cpus machine:
mkdir /sys/fs/cgroup/cpuset/test
cd /sys/fs/cgroup/cpuset/test
echo 1 > cpuset.cpus
echo 0 > cpuset.mems
sleep 100 & echo $! > tasks
sleep 100 & echo $! > tasks
echo 0 > /sys/bus/cpu/devices/cpu1/online

backtrace:
BUG: unable to handle kernel NULL pointer dereference at 0cf8
IP: cpuset_can_attach+0x2f/0x140
Call Trace:
 ? cpuset_attach+0x30f/0x3d0
 cgroup_migrate_execute+0x71/0x3c0
 cgroup_migrate+0x75/0x80
 cgroup_transfer_tasks+0x1b2/0x230
 cpuset_hotplug_workfn+0xa7d/0xce0
 ? finish_task_switch+0x79/0x240
 process_one_work+0x149/0x360
 worker_thread+0x4d/0x3c0

Signed-off-by: Shu Wang 
---
 kernel/cgroup/cgroup-v1.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c
index 024085daab1a..165734573b5e 100644
--- a/kernel/cgroup/cgroup-v1.c
+++ b/kernel/cgroup/cgroup-v1.c
@@ -129,6 +129,12 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup 
*from)
css_task_iter_end();
 
if (task) {
+   /*
+* Reset csets to src_cets, as cgroup_migrate assumes
+* csets is pointing to src_csets.
+*/
+   mgctx.tset.csets = _csets;
+
ret = cgroup_migrate(task, false, );
if (!ret)
trace_cgroup_transfer_tasks(to, task, false);
-- 
2.13.5



[PATCH] kbuild/mkspec: remove firmware from rpm package

2017-09-19 Thread shuwang
From: Shu Wang 

Commit 5620a0d1aacd ("firmware: delete in-kernel firmware") deleted
in-kernel firmware support, including the firmware install command.

So make binrpm-pkg will failed as no firmware_install make target.

Signed-off-by: Shu Wang 
---
 scripts/package/mkspec | 4 
 1 file changed, 4 deletions(-)

diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index bb43f153fd8e..8f34e31d8474 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -88,11 +88,8 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi 
$RPM_BUILD_ROOT/lib/modules'
 echo "%else"
 echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
 echo "%endif"
-echo 'mkdir -p $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
 
 echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= 
mod-fw= modules_install'
-echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
-echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
 echo "%ifarch ia64"
 echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
 echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
@@ -154,7 +151,6 @@ echo '%defattr (-, root, root)'
 echo "/lib/modules/$KERNELRELEASE"
 echo "%exclude /lib/modules/$KERNELRELEASE/build"
 echo "%exclude /lib/modules/$KERNELRELEASE/source"
-echo "/lib/firmware/$KERNELRELEASE"
 echo "/boot/*"
 echo ""
 echo "%files headers"
-- 
2.13.5



[PATCH] kbuild/mkspec: remove firmware from rpm package

2017-09-19 Thread shuwang
From: Shu Wang 

Commit 5620a0d1aacd ("firmware: delete in-kernel firmware") deleted
in-kernel firmware support, including the firmware install command.

So make binrpm-pkg will failed as no firmware_install make target.

Signed-off-by: Shu Wang 
---
 scripts/package/mkspec | 4 
 1 file changed, 4 deletions(-)

diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index bb43f153fd8e..8f34e31d8474 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -88,11 +88,8 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi 
$RPM_BUILD_ROOT/lib/modules'
 echo "%else"
 echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
 echo "%endif"
-echo 'mkdir -p $RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
 
 echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= 
mod-fw= modules_install'
-echo 'INSTALL_FW_PATH=$RPM_BUILD_ROOT'"/lib/firmware/$KERNELRELEASE"
-echo 'make INSTALL_FW_PATH=$INSTALL_FW_PATH' firmware_install
 echo "%ifarch ia64"
 echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
 echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
@@ -154,7 +151,6 @@ echo '%defattr (-, root, root)'
 echo "/lib/modules/$KERNELRELEASE"
 echo "%exclude /lib/modules/$KERNELRELEASE/build"
 echo "%exclude /lib/modules/$KERNELRELEASE/source"
-echo "/lib/firmware/$KERNELRELEASE"
 echo "/boot/*"
 echo ""
 echo "%files headers"
-- 
2.13.5



[PATCH V2] megaraid: kmemleak: Track page allocation for fusion

2017-09-14 Thread shuwang
From: Shu Wang 

Kmemleak reports about a thousand false positives for fusion->
cmd_list[]. Root casue is the cmd_list objects are allocated from
slab allocator, and stored its pointer in object allocated by page
allocator. The fix will tell kmemleak to track and scan fusion
object.

V2:
Add comment, balance braces, move kmemleak_free before free_pages.
checkpatch passed.

Before patch:
kmemleak: 1004 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

unreferenced object 0x88042584e000 (size 8192):
  backtrace:
 kmemleak_alloc+0x4a/0xa0
 __kmalloc+0xec/0x220
 megasas_alloc_cmdlist_fusion+0x3e/0x140 [megaraid_sas]
 megasas_alloc_cmds_fusion+0x44/0x450 [megaraid_sas]
 megasas_init_adapter_fusion+0x21d/0x6e0 [megaraid_sas]
 megasas_init_fw+0x357/0xd30 [megaraid_sas]
 megasas_probe_one.part.34+0x5be/0x1040 [megaraid_sas]
 megasas_probe_one+0x46/0xc0 [megaraid_sas]
 local_pci_probe+0x45/0xa0
 work_for_cpu_fn+0x14/0x20
 process_one_work+0x149/0x360
 worker_thread+0x1d8/0x3c0
 kthread+0x109/0x140
 ret_from_fork+0x25/0x30

Signed-off-by: Shu Wang 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 11bd2e698b84..161b8e5518c0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -4512,6 +4513,13 @@ megasas_alloc_fusion_context(struct megasas_instance 
*instance)
dev_err(>pdev->dev, "Failed from %s %d\n", 
__func__, __LINE__);
return -ENOMEM;
}
+   } else {
+   /*
+* Allow kmemleak to scan these pages as they contain pointers
+* to additional allocations. fusion->cmd_list[].
+*/
+   kmemleak_alloc(instance->ctrl_context,
+   sizeof(struct fusion_context), 1, GFP_KERNEL);
}
 
fusion = instance->ctrl_context;
@@ -4548,9 +4556,11 @@ megasas_free_fusion_context(struct megasas_instance 
*instance)
 
if (is_vmalloc_addr(fusion))
vfree(fusion);
-   else
+   else {
+   kmemleak_free(fusion);
free_pages((ulong)fusion,
instance->ctrl_context_pages);
+   }
}
 }
 
-- 
2.13.5



[PATCH V2] megaraid: kmemleak: Track page allocation for fusion

2017-09-14 Thread shuwang
From: Shu Wang 

Kmemleak reports about a thousand false positives for fusion->
cmd_list[]. Root casue is the cmd_list objects are allocated from
slab allocator, and stored its pointer in object allocated by page
allocator. The fix will tell kmemleak to track and scan fusion
object.

V2:
Add comment, balance braces, move kmemleak_free before free_pages.
checkpatch passed.

Before patch:
kmemleak: 1004 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

unreferenced object 0x88042584e000 (size 8192):
  backtrace:
 kmemleak_alloc+0x4a/0xa0
 __kmalloc+0xec/0x220
 megasas_alloc_cmdlist_fusion+0x3e/0x140 [megaraid_sas]
 megasas_alloc_cmds_fusion+0x44/0x450 [megaraid_sas]
 megasas_init_adapter_fusion+0x21d/0x6e0 [megaraid_sas]
 megasas_init_fw+0x357/0xd30 [megaraid_sas]
 megasas_probe_one.part.34+0x5be/0x1040 [megaraid_sas]
 megasas_probe_one+0x46/0xc0 [megaraid_sas]
 local_pci_probe+0x45/0xa0
 work_for_cpu_fn+0x14/0x20
 process_one_work+0x149/0x360
 worker_thread+0x1d8/0x3c0
 kthread+0x109/0x140
 ret_from_fork+0x25/0x30

Signed-off-by: Shu Wang 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 11bd2e698b84..161b8e5518c0 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -4512,6 +4513,13 @@ megasas_alloc_fusion_context(struct megasas_instance 
*instance)
dev_err(>pdev->dev, "Failed from %s %d\n", 
__func__, __LINE__);
return -ENOMEM;
}
+   } else {
+   /*
+* Allow kmemleak to scan these pages as they contain pointers
+* to additional allocations. fusion->cmd_list[].
+*/
+   kmemleak_alloc(instance->ctrl_context,
+   sizeof(struct fusion_context), 1, GFP_KERNEL);
}
 
fusion = instance->ctrl_context;
@@ -4548,9 +4556,11 @@ megasas_free_fusion_context(struct megasas_instance 
*instance)
 
if (is_vmalloc_addr(fusion))
vfree(fusion);
-   else
+   else {
+   kmemleak_free(fusion);
free_pages((ulong)fusion,
instance->ctrl_context_pages);
+   }
}
 }
 
-- 
2.13.5



[PATCH] megaraid: kmemleak: Track page allocation for fusion

2017-09-14 Thread shuwang
From: Shu Wang 

Kmemleak reports about a thousand false positives for fusion->
cmd_list[]. Root casue is the cmd_list objects are allocated from
slab allocator, and stored its pointer in object allocated by page
allocator. The fix will tell kmemleak to track and scan fusion
object.

Before patch:
kmemleak: 1004 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

unreferenced object 0x88042584e000 (size 8192):
  backtrace:
 kmemleak_alloc+0x4a/0xa0
 __kmalloc+0xec/0x220
 megasas_alloc_cmdlist_fusion+0x3e/0x140 [megaraid_sas]
 megasas_alloc_cmds_fusion+0x44/0x450 [megaraid_sas]
 megasas_init_adapter_fusion+0x21d/0x6e0 [megaraid_sas]
 megasas_init_fw+0x357/0xd30 [megaraid_sas]
 megasas_probe_one.part.34+0x5be/0x1040 [megaraid_sas]
 megasas_probe_one+0x46/0xc0 [megaraid_sas]
 local_pci_probe+0x45/0xa0
 work_for_cpu_fn+0x14/0x20
 process_one_work+0x149/0x360
 worker_thread+0x1d8/0x3c0
 kthread+0x109/0x140
 ret_from_fork+0x25/0x30

Signed-off-by: Shu Wang 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 11bd2e698b84..621299edd8de 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -4512,7 +4513,9 @@ megasas_alloc_fusion_context(struct megasas_instance 
*instance)
dev_err(>pdev->dev, "Failed from %s %d\n", 
__func__, __LINE__);
return -ENOMEM;
}
-   }
+   } else
+   kmemleak_alloc(instance->ctrl_context,
+   sizeof(struct fusion_context), 1, GFP_KERNEL);
 
fusion = instance->ctrl_context;
 
@@ -4548,9 +4551,11 @@ megasas_free_fusion_context(struct megasas_instance 
*instance)
 
if (is_vmalloc_addr(fusion))
vfree(fusion);
-   else
+   else {
free_pages((ulong)fusion,
instance->ctrl_context_pages);
+   kmemleak_free(fusion);
+   }
}
 }
 
-- 
2.13.5



[PATCH] megaraid: kmemleak: Track page allocation for fusion

2017-09-14 Thread shuwang
From: Shu Wang 

Kmemleak reports about a thousand false positives for fusion->
cmd_list[]. Root casue is the cmd_list objects are allocated from
slab allocator, and stored its pointer in object allocated by page
allocator. The fix will tell kmemleak to track and scan fusion
object.

Before patch:
kmemleak: 1004 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

unreferenced object 0x88042584e000 (size 8192):
  backtrace:
 kmemleak_alloc+0x4a/0xa0
 __kmalloc+0xec/0x220
 megasas_alloc_cmdlist_fusion+0x3e/0x140 [megaraid_sas]
 megasas_alloc_cmds_fusion+0x44/0x450 [megaraid_sas]
 megasas_init_adapter_fusion+0x21d/0x6e0 [megaraid_sas]
 megasas_init_fw+0x357/0xd30 [megaraid_sas]
 megasas_probe_one.part.34+0x5be/0x1040 [megaraid_sas]
 megasas_probe_one+0x46/0xc0 [megaraid_sas]
 local_pci_probe+0x45/0xa0
 work_for_cpu_fn+0x14/0x20
 process_one_work+0x149/0x360
 worker_thread+0x1d8/0x3c0
 kthread+0x109/0x140
 ret_from_fork+0x25/0x30

Signed-off-by: Shu Wang 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 11bd2e698b84..621299edd8de 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -4512,7 +4513,9 @@ megasas_alloc_fusion_context(struct megasas_instance 
*instance)
dev_err(>pdev->dev, "Failed from %s %d\n", 
__func__, __LINE__);
return -ENOMEM;
}
-   }
+   } else
+   kmemleak_alloc(instance->ctrl_context,
+   sizeof(struct fusion_context), 1, GFP_KERNEL);
 
fusion = instance->ctrl_context;
 
@@ -4548,9 +4551,11 @@ megasas_free_fusion_context(struct megasas_instance 
*instance)
 
if (is_vmalloc_addr(fusion))
vfree(fusion);
-   else
+   else {
free_pages((ulong)fusion,
instance->ctrl_context_pages);
+   kmemleak_free(fusion);
+   }
}
 }
 
-- 
2.13.5



[PATCH] ftrace: fix kmemleak in unregister_ftrace_graph

2017-09-11 Thread shuwang
From: Shu Wang 

The trampoline allocated by function tracer was
overwrite by function_graph tracer, and cause
memory leak. The save_global_trampoline should
save previous trampoline in register_ftrace_graph
and restore it in unregister_ftrace_graph. But
as it implemented, save_global_trampoline was only
used in unregister_ftrace_graph as default value 0,
and overwrite the previous trampoline's value.

kmmeleak backtrace:
kmemleak_vmalloc+0x77/0xc0
__vmalloc_node_range+0x1b5/0x2c0
module_alloc+0x7c/0xd0
arch_ftrace_update_trampoline+0xb5/0x290
ftrace_startup+0x78/0x210
register_ftrace_function+0x8b/0xd0
function_trace_init+0x4f/0x80
tracing_set_tracer+0xe6/0x170
tracing_set_trace_write+0x90/0xd0
__vfs_write+0x37/0x170
vfs_write+0xb2/0x1b0
SyS_write+0x55/0xc0
do_syscall_64+0x67/0x180
return_from_SYSCALL_64+0x0/0x6a

Signed-off-by: Shu Wang 
---
 kernel/trace/ftrace.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 6abfafd7f173..8319e09e15b9 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4954,9 +4954,6 @@ static char ftrace_graph_buf[FTRACE_FILTER_SIZE] 
__initdata;
 static char ftrace_graph_notrace_buf[FTRACE_FILTER_SIZE] __initdata;
 static int ftrace_graph_set_hash(struct ftrace_hash *hash, char *buffer);
 
-static unsigned long save_global_trampoline;
-static unsigned long save_global_flags;
-
 static int __init set_graph_function(char *str)
 {
strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
@@ -6808,17 +6805,6 @@ void unregister_ftrace_graph(void)
unregister_pm_notifier(_suspend_notifier);
unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
 
-#ifdef CONFIG_DYNAMIC_FTRACE
-   /*
-* Function graph does not allocate the trampoline, but
-* other global_ops do. We need to reset the ALLOC_TRAMP flag
-* if one was used.
-*/
-   global_ops.trampoline = save_global_trampoline;
-   if (save_global_flags & FTRACE_OPS_FL_ALLOC_TRAMP)
-   global_ops.flags |= FTRACE_OPS_FL_ALLOC_TRAMP;
-#endif
-
  out:
mutex_unlock(_lock);
 }
-- 
2.13.5



[PATCH] ftrace: fix kmemleak in unregister_ftrace_graph

2017-09-11 Thread shuwang
From: Shu Wang 

The trampoline allocated by function tracer was
overwrite by function_graph tracer, and cause
memory leak. The save_global_trampoline should
save previous trampoline in register_ftrace_graph
and restore it in unregister_ftrace_graph. But
as it implemented, save_global_trampoline was only
used in unregister_ftrace_graph as default value 0,
and overwrite the previous trampoline's value.

kmmeleak backtrace:
kmemleak_vmalloc+0x77/0xc0
__vmalloc_node_range+0x1b5/0x2c0
module_alloc+0x7c/0xd0
arch_ftrace_update_trampoline+0xb5/0x290
ftrace_startup+0x78/0x210
register_ftrace_function+0x8b/0xd0
function_trace_init+0x4f/0x80
tracing_set_tracer+0xe6/0x170
tracing_set_trace_write+0x90/0xd0
__vfs_write+0x37/0x170
vfs_write+0xb2/0x1b0
SyS_write+0x55/0xc0
do_syscall_64+0x67/0x180
return_from_SYSCALL_64+0x0/0x6a

Signed-off-by: Shu Wang 
---
 kernel/trace/ftrace.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 6abfafd7f173..8319e09e15b9 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4954,9 +4954,6 @@ static char ftrace_graph_buf[FTRACE_FILTER_SIZE] 
__initdata;
 static char ftrace_graph_notrace_buf[FTRACE_FILTER_SIZE] __initdata;
 static int ftrace_graph_set_hash(struct ftrace_hash *hash, char *buffer);
 
-static unsigned long save_global_trampoline;
-static unsigned long save_global_flags;
-
 static int __init set_graph_function(char *str)
 {
strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
@@ -6808,17 +6805,6 @@ void unregister_ftrace_graph(void)
unregister_pm_notifier(_suspend_notifier);
unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
 
-#ifdef CONFIG_DYNAMIC_FTRACE
-   /*
-* Function graph does not allocate the trampoline, but
-* other global_ops do. We need to reset the ALLOC_TRAMP flag
-* if one was used.
-*/
-   global_ops.trampoline = save_global_trampoline;
-   if (save_global_flags & FTRACE_OPS_FL_ALLOC_TRAMP)
-   global_ops.flags |= FTRACE_OPS_FL_ALLOC_TRAMP;
-#endif
-
  out:
mutex_unlock(_lock);
 }
-- 
2.13.5



[PATCH] cifs: release auth_key.response for reconnect.

2017-09-08 Thread shuwang
From: Shu Wang 

There is a race that cause cifs reconnect in cifs_mount,
- cifs_mount
  - cifs_get_tcp_session
- [ start thread cifs_demultiplex_thread
  - cifs_read_from_socket: -ECONNABORTED
- DELAY_WORK smb2_reconnect_server ]
  - cifs_setup_session
  - [ smb2_reconnect_server ]

auth_key.response was allocated in cifs_setup_session, and
will release when the session destoried. So when session re-
connect, auth_key.response should be check and released.

Tested with my system:
CIFS VFS: Free previous auth_key.response = 8800320bbf80

A simple auth_key.response allocation call trace:
- cifs_setup_session
- SMB2_sess_setup
- SMB2_sess_auth_rawntlmssp_authenticate
- build_ntlmssp_auth_blob
- setup_ntlmv2_rsp

Signed-off-by: Shu Wang 
---
 fs/cifs/connect.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 83a8f52cd879..5a97744161c1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -4143,6 +4143,14 @@ cifs_setup_session(const unsigned int xid, struct 
cifs_ses *ses,
cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
 server->sec_mode, server->capabilities, server->timeAdj);
 
+   if (ses->auth_key.response) {
+   cifs_dbg(VFS, "Free previous auth_key.response = %p\n",
+ses->auth_key.response);
+   kfree(ses->auth_key.response);
+   ses->auth_key.response = NULL;
+   ses->auth_key.len = 0;
+   }
+
if (server->ops->sess_setup)
rc = server->ops->sess_setup(xid, ses, nls_info);
 
-- 
2.13.5



[PATCH] cifs: release auth_key.response for reconnect.

2017-09-08 Thread shuwang
From: Shu Wang 

There is a race that cause cifs reconnect in cifs_mount,
- cifs_mount
  - cifs_get_tcp_session
- [ start thread cifs_demultiplex_thread
  - cifs_read_from_socket: -ECONNABORTED
- DELAY_WORK smb2_reconnect_server ]
  - cifs_setup_session
  - [ smb2_reconnect_server ]

auth_key.response was allocated in cifs_setup_session, and
will release when the session destoried. So when session re-
connect, auth_key.response should be check and released.

Tested with my system:
CIFS VFS: Free previous auth_key.response = 8800320bbf80

A simple auth_key.response allocation call trace:
- cifs_setup_session
- SMB2_sess_setup
- SMB2_sess_auth_rawntlmssp_authenticate
- build_ntlmssp_auth_blob
- setup_ntlmv2_rsp

Signed-off-by: Shu Wang 
---
 fs/cifs/connect.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 83a8f52cd879..5a97744161c1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -4143,6 +4143,14 @@ cifs_setup_session(const unsigned int xid, struct 
cifs_ses *ses,
cifs_dbg(FYI, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d\n",
 server->sec_mode, server->capabilities, server->timeAdj);
 
+   if (ses->auth_key.response) {
+   cifs_dbg(VFS, "Free previous auth_key.response = %p\n",
+ses->auth_key.response);
+   kfree(ses->auth_key.response);
+   ses->auth_key.response = NULL;
+   ses->auth_key.len = 0;
+   }
+
if (server->ops->sess_setup)
rc = server->ops->sess_setup(xid, ses, nls_info);
 
-- 
2.13.5



[PATCH] cifs: release cifs root_cred after exit_cifs

2017-09-07 Thread shuwang
From: Shu Wang 

memory leak was found by kmemleak. exit_cifs_spnego
should be called before cifs module removed, or
cifs root_cred will not be released.

kmemleak report:
unreferenced object 0x880070a3ce40 (size 192):
  backtrace:
 kmemleak_alloc+0x4a/0xa0
 kmem_cache_alloc+0xc7/0x1d0
 prepare_kernel_cred+0x20/0x120
 init_cifs_spnego+0x2d/0x170 [cifs]
 0xc07801f3
 do_one_initcall+0x51/0x1b0
 do_init_module+0x60/0x1fd
 load_module+0x161e/0x1b60
 SYSC_finit_module+0xa9/0x100
 SyS_finit_module+0xe/0x10

Signed-off-by: Shu Wang 
---
 fs/cifs/cifsfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 180b3356ff86..a92bdb89bde3 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1447,7 +1447,7 @@ exit_cifs(void)
exit_cifs_idmap();
 #endif
 #ifdef CONFIG_CIFS_UPCALL
-   unregister_key_type(_spnego_key_type);
+   exit_cifs_spnego();
 #endif
cifs_destroy_request_bufs();
cifs_destroy_mids();
-- 
2.13.5



[PATCH] cifs: release cifs root_cred after exit_cifs

2017-09-07 Thread shuwang
From: Shu Wang 

memory leak was found by kmemleak. exit_cifs_spnego
should be called before cifs module removed, or
cifs root_cred will not be released.

kmemleak report:
unreferenced object 0x880070a3ce40 (size 192):
  backtrace:
 kmemleak_alloc+0x4a/0xa0
 kmem_cache_alloc+0xc7/0x1d0
 prepare_kernel_cred+0x20/0x120
 init_cifs_spnego+0x2d/0x170 [cifs]
 0xc07801f3
 do_one_initcall+0x51/0x1b0
 do_init_module+0x60/0x1fd
 load_module+0x161e/0x1b60
 SYSC_finit_module+0xa9/0x100
 SyS_finit_module+0xe/0x10

Signed-off-by: Shu Wang 
---
 fs/cifs/cifsfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 180b3356ff86..a92bdb89bde3 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -1447,7 +1447,7 @@ exit_cifs(void)
exit_cifs_idmap();
 #endif
 #ifdef CONFIG_CIFS_UPCALL
-   unregister_key_type(_spnego_key_type);
+   exit_cifs_spnego();
 #endif
cifs_destroy_request_bufs();
cifs_destroy_mids();
-- 
2.13.5



[PATCH 1/1] sched/topology: fix memleak in __sdt_alloc()

2017-08-10 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak. the sg and sgc from __sdt_alloc()
might be leaked as each domain holds many groups' ref. And in
destroy_sched_domain(), it only declined the first group ref.

Online and offline a cpu can trigger this leak, and cause OOM.
reproducer for my 6 cpus machine:
while true
do
echo 0 > /sys/devices/system/cpu/cpu5/online;
echo 1 > /sys/devices/system/cpu/cpu5/online;
done

unreferenced object 0x88007d772a80 (size 64):
  comm "cpuhp/5", pid 39, jiffies 4294719962 (age 35.251s)
  hex dump (first 32 bytes):
c0 22 77 7d 00 88 ff ff 02 00 00 00 01 00 00 00  ."w}
40 2a 77 7d 00 88 ff ff 00 00 00 00 00 00 00 00  @*w}
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] __kmalloc_node+0xf1/0x280
[] build_sched_domains+0x1e8/0xf20
[] partition_sched_domains+0x304/0x360
[] cpuset_update_active_cpus+0x17/0x40
[] sched_cpu_activate+0xae/0xc0
[] cpuhp_invoke_callback+0x90/0x400
[] cpuhp_up_callbacks+0x37/0xb0
[] cpuhp_thread_fun+0xd7/0xf0
[] smpboot_thread_fn+0x110/0x160
[] kthread+0x109/0x140
[] ret_from_fork+0x25/0x30
[] 0x
unreferenced object 0x88007d772a40 (size 64):
  comm "cpuhp/5", pid 39, jiffies 4294719962 (age 35.251s)
  hex dump (first 32 bytes):
03 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00  
00 04 00 00 00 00 00 00 4f 3c fc ff 00 00 00 00  O<..
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] __kmalloc_node+0xf1/0x280
[] build_sched_domains+0xead/0xf20
[] partition_sched_domains+0x304/0x360
[] cpuset_update_active_cpus+0x17/0x40
[] sched_cpu_activate+0xae/0xc0
[] cpuhp_invoke_callback+0x90/0x400
[] cpuhp_up_callbacks+0x37/0xb0
[] cpuhp_thread_fun+0xd7/0xf0
[] smpboot_thread_fn+0x110/0x160
[] kthread+0x109/0x140
[] ret_from_fork+0x25/0x30
[] 0x

Reported-by: Chunyu Hu 
Signed-off-by: Chunyu Hu 
Signed-off-by: Shu Wang 
---
 kernel/sched/topology.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 79895ae..35c3c4d 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -337,7 +337,8 @@ static void free_sched_groups(struct sched_group *sg, int 
free_sgc)
if (free_sgc && atomic_dec_and_test(>sgc->ref))
kfree(sg->sgc);
 
-   kfree(sg);
+   if (atomic_dec_and_test(>ref))
+   kfree(sg);
sg = tmp;
} while (sg != first);
 }
@@ -345,15 +346,11 @@ static void free_sched_groups(struct sched_group *sg, int 
free_sgc)
 static void destroy_sched_domain(struct sched_domain *sd)
 {
/*
-* If its an overlapping domain it has private groups, iterate and
-* nuke them all.
+* A sched domain has many groups' reference, and an overlapping
+* domain has private groups, iterate and nuck them all.
 */
-   if (sd->flags & SD_OVERLAP) {
-   free_sched_groups(sd->groups, 1);
-   } else if (atomic_dec_and_test(>groups->ref)) {
-   kfree(sd->groups->sgc);
-   kfree(sd->groups);
-   }
+   free_sched_groups(sd->groups, 1);
+
if (sd->shared && atomic_dec_and_test(>shared->ref))
kfree(sd->shared);
kfree(sd);
@@ -670,6 +667,7 @@ build_group_from_child_sched_domain(struct sched_domain 
*sd, int cpu)
else
cpumask_copy(sg_span, sched_domain_span(sd));
 
+   atomic_inc(>ref);
return sg;
 }
 
-- 
2.5.0



[PATCH 1/1] sched/topology: fix memleak in __sdt_alloc()

2017-08-10 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak. the sg and sgc from __sdt_alloc()
might be leaked as each domain holds many groups' ref. And in
destroy_sched_domain(), it only declined the first group ref.

Online and offline a cpu can trigger this leak, and cause OOM.
reproducer for my 6 cpus machine:
while true
do
echo 0 > /sys/devices/system/cpu/cpu5/online;
echo 1 > /sys/devices/system/cpu/cpu5/online;
done

unreferenced object 0x88007d772a80 (size 64):
  comm "cpuhp/5", pid 39, jiffies 4294719962 (age 35.251s)
  hex dump (first 32 bytes):
c0 22 77 7d 00 88 ff ff 02 00 00 00 01 00 00 00  ."w}
40 2a 77 7d 00 88 ff ff 00 00 00 00 00 00 00 00  @*w}
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] __kmalloc_node+0xf1/0x280
[] build_sched_domains+0x1e8/0xf20
[] partition_sched_domains+0x304/0x360
[] cpuset_update_active_cpus+0x17/0x40
[] sched_cpu_activate+0xae/0xc0
[] cpuhp_invoke_callback+0x90/0x400
[] cpuhp_up_callbacks+0x37/0xb0
[] cpuhp_thread_fun+0xd7/0xf0
[] smpboot_thread_fn+0x110/0x160
[] kthread+0x109/0x140
[] ret_from_fork+0x25/0x30
[] 0x
unreferenced object 0x88007d772a40 (size 64):
  comm "cpuhp/5", pid 39, jiffies 4294719962 (age 35.251s)
  hex dump (first 32 bytes):
03 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00  
00 04 00 00 00 00 00 00 4f 3c fc ff 00 00 00 00  O<..
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] __kmalloc_node+0xf1/0x280
[] build_sched_domains+0xead/0xf20
[] partition_sched_domains+0x304/0x360
[] cpuset_update_active_cpus+0x17/0x40
[] sched_cpu_activate+0xae/0xc0
[] cpuhp_invoke_callback+0x90/0x400
[] cpuhp_up_callbacks+0x37/0xb0
[] cpuhp_thread_fun+0xd7/0xf0
[] smpboot_thread_fn+0x110/0x160
[] kthread+0x109/0x140
[] ret_from_fork+0x25/0x30
[] 0x

Reported-by: Chunyu Hu 
Signed-off-by: Chunyu Hu 
Signed-off-by: Shu Wang 
---
 kernel/sched/topology.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 79895ae..35c3c4d 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -337,7 +337,8 @@ static void free_sched_groups(struct sched_group *sg, int 
free_sgc)
if (free_sgc && atomic_dec_and_test(>sgc->ref))
kfree(sg->sgc);
 
-   kfree(sg);
+   if (atomic_dec_and_test(>ref))
+   kfree(sg);
sg = tmp;
} while (sg != first);
 }
@@ -345,15 +346,11 @@ static void free_sched_groups(struct sched_group *sg, int 
free_sgc)
 static void destroy_sched_domain(struct sched_domain *sd)
 {
/*
-* If its an overlapping domain it has private groups, iterate and
-* nuke them all.
+* A sched domain has many groups' reference, and an overlapping
+* domain has private groups, iterate and nuck them all.
 */
-   if (sd->flags & SD_OVERLAP) {
-   free_sched_groups(sd->groups, 1);
-   } else if (atomic_dec_and_test(>groups->ref)) {
-   kfree(sd->groups->sgc);
-   kfree(sd->groups);
-   }
+   free_sched_groups(sd->groups, 1);
+
if (sd->shared && atomic_dec_and_test(>shared->ref))
kfree(sd->shared);
kfree(sd);
@@ -670,6 +667,7 @@ build_group_from_child_sched_domain(struct sched_domain 
*sd, int cpu)
else
cpumask_copy(sg_span, sched_domain_span(sd));
 
+   atomic_inc(>ref);
return sg;
 }
 
-- 
2.5.0



[PATCH v2] kmemleak: add oom=<disable|ignore> runtime parameter

2017-07-24 Thread shuwang
From: Shu Wang 

When running memory stress tests, kmemleak could be easily disabled in
function create_object as system is out of memory and kmemleak failed to
alloc from object_cache. Since there's no way to enable kmemleak after
it's off, simply ignore the object_cache alloc failure will just loses
track of some memory objects, but could increase the usability of kmemleak
under memory stress.

The default action for oom is still disable kmemleak,
echo oom=ignore > /sys/kernel/debug/kmemleak can change to action to
ignore oom.

Signed-off-by: Shu Wang 
---
 Documentation/dev-tools/kmemleak.rst |  5 +
 mm/kmemleak.c| 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kmemleak.rst 
b/Documentation/dev-tools/kmemleak.rst
index cb88626..3013809 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -60,6 +60,11 @@ Memory scanning parameters can be modified at run-time by 
writing to the
 or free all kmemleak objects if kmemleak has been disabled.
 - dump=
 dump information about the object found at 
+- oom=disable
+disable kmemleak after system out of memory (default)
+- oom=ignore
+do not disable kmemleak after system out of memory
+(useful for memory stress test, but will lose some objects)
 
 Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
 the kernel command line.
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd8..b5cb2c6 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -236,6 +236,9 @@ static DEFINE_MUTEX(scan_mutex);
 static int kmemleak_skip_disable;
 /* If there are leaks that can be reported */
 static bool kmemleak_found_leaks;
+/* If disable kmemleak after out of memory */
+static bool kmemleak_oom_disable = true;
+
 
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
@@ -556,7 +559,8 @@ static struct kmemleak_object *create_object(unsigned long 
ptr, size_t size,
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
pr_warn("Cannot allocate a kmemleak_object structure\n");
-   kmemleak_disable();
+   if (kmemleak_oom_disable)
+   kmemleak_disable();
return NULL;
}
 
@@ -1888,6 +1892,10 @@ static ssize_t kmemleak_write(struct file *file, const 
char __user *user_buf,
kmemleak_scan();
else if (strncmp(buf, "dump=", 5) == 0)
ret = dump_str_object_info(buf + 5);
+   else if (strncmp(buf, "oom=ignore", 10) == 0)
+   kmemleak_oom_disable = false;
+   else if (strncmp(buf, "oom=disable", 11) == 0)
+   kmemleak_oom_disable = true;
else
ret = -EINVAL;
 
-- 
2.5.0



[PATCH v2] kmemleak: add oom= runtime parameter

2017-07-24 Thread shuwang
From: Shu Wang 

When running memory stress tests, kmemleak could be easily disabled in
function create_object as system is out of memory and kmemleak failed to
alloc from object_cache. Since there's no way to enable kmemleak after
it's off, simply ignore the object_cache alloc failure will just loses
track of some memory objects, but could increase the usability of kmemleak
under memory stress.

The default action for oom is still disable kmemleak,
echo oom=ignore > /sys/kernel/debug/kmemleak can change to action to
ignore oom.

Signed-off-by: Shu Wang 
---
 Documentation/dev-tools/kmemleak.rst |  5 +
 mm/kmemleak.c| 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kmemleak.rst 
b/Documentation/dev-tools/kmemleak.rst
index cb88626..3013809 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -60,6 +60,11 @@ Memory scanning parameters can be modified at run-time by 
writing to the
 or free all kmemleak objects if kmemleak has been disabled.
 - dump=
 dump information about the object found at 
+- oom=disable
+disable kmemleak after system out of memory (default)
+- oom=ignore
+do not disable kmemleak after system out of memory
+(useful for memory stress test, but will lose some objects)
 
 Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
 the kernel command line.
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd8..b5cb2c6 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -236,6 +236,9 @@ static DEFINE_MUTEX(scan_mutex);
 static int kmemleak_skip_disable;
 /* If there are leaks that can be reported */
 static bool kmemleak_found_leaks;
+/* If disable kmemleak after out of memory */
+static bool kmemleak_oom_disable = true;
+
 
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
@@ -556,7 +559,8 @@ static struct kmemleak_object *create_object(unsigned long 
ptr, size_t size,
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
pr_warn("Cannot allocate a kmemleak_object structure\n");
-   kmemleak_disable();
+   if (kmemleak_oom_disable)
+   kmemleak_disable();
return NULL;
}
 
@@ -1888,6 +1892,10 @@ static ssize_t kmemleak_write(struct file *file, const 
char __user *user_buf,
kmemleak_scan();
else if (strncmp(buf, "dump=", 5) == 0)
ret = dump_str_object_info(buf + 5);
+   else if (strncmp(buf, "oom=ignore", 10) == 0)
+   kmemleak_oom_disable = false;
+   else if (strncmp(buf, "oom=disable", 11) == 0)
+   kmemleak_oom_disable = true;
else
ret = -EINVAL;
 
-- 
2.5.0



[PATCH] scsi: megaraid_sas: fix memleak in megasas_alloc_cmdlist_fusion

2017-07-21 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak, a few kb mem was leaked in
megasas_alloc_cmdlist_fusion when kzalloc failed for one
megasas_cmd_fusion allocation.

unreferenced object 0x88045dbd2000 (size 8192):
  comm "systemd-udevd", pid 323, jiffies 4294671759 (age 49.008s)
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] __kmalloc+0xe8/0x220
[] megasas_alloc_cmdlist_fusion+0x34/0xe0 [megaraid_sas]
(gdb) list *megasas_alloc_cmdlist_fusion+0x34
0xd5c4 is in megasas_alloc_cmdlist_fusion
   (drivers/scsi/megaraid/megaraid_sas_fusion.c:443).
[] megasas_alloc_cmds_fusion+0x25/0x410 [megaraid_sas]
[] megasas_init_adapter_fusion+0x21f/0x640 [megaraid_sas]
[] megasas_init_fw+0x357/0xd30 [megaraid_sas]
[] megasas_probe_one.part.33+0x636/0x1100 [megaraid_sas]
[] megasas_probe_one+0x46/0xc0 [megaraid_sas]
[] local_pci_probe+0x45/0xa0
[] pci_device_probe+0x192/0x1b0
[] driver_probe_device+0x2a8/0x460
[] __driver_attach+0xdd/0xe0
[] bus_for_each_dev+0x6c/0xc0
[] driver_attach+0x1e/0x20
[] bus_add_driver+0x45/0x270
[] driver_register+0x60/0xe0
unreferenced object 0x880454ce3600 (size 192):
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_trace+0xca/0x1d0
[] megasas_alloc_cmdlist_fusion+0x77/0xe0 [megaraid_sas]
(gdb) list *megasas_alloc_cmdlist_fusion+0x77
0xd607 is in megasas_alloc_cmdlist_fusion
(drivers/scsi/megaraid/megaraid_sas_fusion.c:450).
[] megasas_alloc_cmds_fusion+0x25/0x410 [megaraid_sas]
[] megasas_init_adapter_fusion+0x21f/0x640 [megaraid_sas]
[] megasas_init_fw+0x357/0xd30 [megaraid_sas]
[] megasas_probe_one.part.33+0x636/0x1100 [megaraid_sas]
[] megasas_probe_one+0x46/0xc0 [megaraid_sas]
[] local_pci_probe+0x45/0xa0
[] pci_device_probe+0x192/0x1b0
[] driver_probe_device+0x2a8/0x460
[] __driver_attach+0xdd/0xe0
[] bus_for_each_dev+0x6c/0xc0
[] driver_attach+0x1e/0x20
[] bus_add_driver+0x45/0x270
[] driver_register+0x60/0xe0

Signed-off-by: Shu Wang 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index f990ab4d..9855106 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -425,7 +425,7 @@ static int megasas_create_sg_sense_fusion(struct 
megasas_instance *instance)
 int
 megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)
 {
-   u32 max_mpt_cmd, i;
+   u32 max_mpt_cmd, i, j;
struct fusion_context *fusion;
 
fusion = instance->ctrl_context;
@@ -450,11 +450,15 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance 
*instance)
fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion),
  GFP_KERNEL);
if (!fusion->cmd_list[i]) {
+   for (j = 0; j < i; j++)
+   kfree(fusion->cmd_list[j]);
+   kfree(fusion->cmd_list);
dev_err(>pdev->dev,
"Failed from %s %d\n",  __func__, __LINE__);
return -ENOMEM;
}
}
+
return 0;
 }
 int
-- 
2.5.0



[PATCH] scsi: megaraid_sas: fix memleak in megasas_alloc_cmdlist_fusion

2017-07-21 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak, a few kb mem was leaked in
megasas_alloc_cmdlist_fusion when kzalloc failed for one
megasas_cmd_fusion allocation.

unreferenced object 0x88045dbd2000 (size 8192):
  comm "systemd-udevd", pid 323, jiffies 4294671759 (age 49.008s)
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] __kmalloc+0xe8/0x220
[] megasas_alloc_cmdlist_fusion+0x34/0xe0 [megaraid_sas]
(gdb) list *megasas_alloc_cmdlist_fusion+0x34
0xd5c4 is in megasas_alloc_cmdlist_fusion
   (drivers/scsi/megaraid/megaraid_sas_fusion.c:443).
[] megasas_alloc_cmds_fusion+0x25/0x410 [megaraid_sas]
[] megasas_init_adapter_fusion+0x21f/0x640 [megaraid_sas]
[] megasas_init_fw+0x357/0xd30 [megaraid_sas]
[] megasas_probe_one.part.33+0x636/0x1100 [megaraid_sas]
[] megasas_probe_one+0x46/0xc0 [megaraid_sas]
[] local_pci_probe+0x45/0xa0
[] pci_device_probe+0x192/0x1b0
[] driver_probe_device+0x2a8/0x460
[] __driver_attach+0xdd/0xe0
[] bus_for_each_dev+0x6c/0xc0
[] driver_attach+0x1e/0x20
[] bus_add_driver+0x45/0x270
[] driver_register+0x60/0xe0
unreferenced object 0x880454ce3600 (size 192):
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_trace+0xca/0x1d0
[] megasas_alloc_cmdlist_fusion+0x77/0xe0 [megaraid_sas]
(gdb) list *megasas_alloc_cmdlist_fusion+0x77
0xd607 is in megasas_alloc_cmdlist_fusion
(drivers/scsi/megaraid/megaraid_sas_fusion.c:450).
[] megasas_alloc_cmds_fusion+0x25/0x410 [megaraid_sas]
[] megasas_init_adapter_fusion+0x21f/0x640 [megaraid_sas]
[] megasas_init_fw+0x357/0xd30 [megaraid_sas]
[] megasas_probe_one.part.33+0x636/0x1100 [megaraid_sas]
[] megasas_probe_one+0x46/0xc0 [megaraid_sas]
[] local_pci_probe+0x45/0xa0
[] pci_device_probe+0x192/0x1b0
[] driver_probe_device+0x2a8/0x460
[] __driver_attach+0xdd/0xe0
[] bus_for_each_dev+0x6c/0xc0
[] driver_attach+0x1e/0x20
[] bus_add_driver+0x45/0x270
[] driver_register+0x60/0xe0

Signed-off-by: Shu Wang 
---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c 
b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index f990ab4d..9855106 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -425,7 +425,7 @@ static int megasas_create_sg_sense_fusion(struct 
megasas_instance *instance)
 int
 megasas_alloc_cmdlist_fusion(struct megasas_instance *instance)
 {
-   u32 max_mpt_cmd, i;
+   u32 max_mpt_cmd, i, j;
struct fusion_context *fusion;
 
fusion = instance->ctrl_context;
@@ -450,11 +450,15 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance 
*instance)
fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion),
  GFP_KERNEL);
if (!fusion->cmd_list[i]) {
+   for (j = 0; j < i; j++)
+   kfree(fusion->cmd_list[j]);
+   kfree(fusion->cmd_list);
dev_err(>pdev->dev,
"Failed from %s %d\n",  __func__, __LINE__);
return -ENOMEM;
}
}
+
return 0;
 }
 int
-- 
2.5.0



[PATCH] xhci: fix memleak in xhci_run()

2017-07-19 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak.
xhci_run() did not check return val and free command for
xhci_queue_vendor_command()

unreferenced object 0x88011c0be500 (size 64):
  comm "kworker/0:1", pid 58, jiffies 4294670908 (age 50.420s)
  hex dump (first 32 bytes):
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_trace+0xca/0x1d0
[] xhci_alloc_command+0x44/0x130
[] xhci_run+0x4cc/0x630
[] usb_add_hcd+0x3bb/0x950
[] usb_hcd_pci_probe+0x188/0x500
[] xhci_pci_probe+0x2c/0x220
[] local_pci_probe+0x45/0xa0
[] work_for_cpu_fn+0x14/0x20
[] process_one_work+0x149/0x360
[] worker_thread+0x1d8/0x3c0
[] kthread+0x109/0x140
[] ret_from_fork+0x25/0x30
[] 0x

Signed-off-by: Shu Wang 
---
 drivers/usb/host/xhci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 56f85df..b2a8179 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -622,8 +622,10 @@ int xhci_run(struct usb_hcd *hcd)
if (!command)
return -ENOMEM;
 
-   xhci_queue_vendor_command(xhci, command, 0, 0, 0,
+   ret = xhci_queue_vendor_command(xhci, command, 0, 0, 0,
TRB_TYPE(TRB_NEC_GET_FW));
+   if (ret)
+   xhci_free_command(xhci, command);
}
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB2 roothub");
-- 
2.5.0



[PATCH] xhci: fix memleak in xhci_run()

2017-07-19 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak.
xhci_run() did not check return val and free command for
xhci_queue_vendor_command()

unreferenced object 0x88011c0be500 (size 64):
  comm "kworker/0:1", pid 58, jiffies 4294670908 (age 50.420s)
  hex dump (first 32 bytes):
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_trace+0xca/0x1d0
[] xhci_alloc_command+0x44/0x130
[] xhci_run+0x4cc/0x630
[] usb_add_hcd+0x3bb/0x950
[] usb_hcd_pci_probe+0x188/0x500
[] xhci_pci_probe+0x2c/0x220
[] local_pci_probe+0x45/0xa0
[] work_for_cpu_fn+0x14/0x20
[] process_one_work+0x149/0x360
[] worker_thread+0x1d8/0x3c0
[] kthread+0x109/0x140
[] ret_from_fork+0x25/0x30
[] 0x

Signed-off-by: Shu Wang 
---
 drivers/usb/host/xhci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 56f85df..b2a8179 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -622,8 +622,10 @@ int xhci_run(struct usb_hcd *hcd)
if (!command)
return -ENOMEM;
 
-   xhci_queue_vendor_command(xhci, command, 0, 0, 0,
+   ret = xhci_queue_vendor_command(xhci, command, 0, 0, 0,
TRB_TYPE(TRB_NEC_GET_FW));
+   if (ret)
+   xhci_free_command(xhci, command);
}
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Finished xhci_run for USB2 roothub");
-- 
2.5.0



[PATCH] x86/microcode/AMD: fix memleak in update_cache()

2017-07-18 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak. The mem is allocated in
verify_and_add_patch(), passed to update_cache(patch),
and just dropped the reference without free
if (p->patch_id >= new_patch->patch_id)
return;

unreferenced object 0x88010e780b40 (size 32):
  comm "bash", pid 860, jiffies 4294690939 (age 29.297s)
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_trace+0xca/0x1d0
[] load_microcode_amd.isra.0+0x1d0/0x400
[] request_microcode_amd+0xc3/0x160
[] reload_store+0xe1/0x170
[] dev_attr_store+0x18/0x30
[] sysfs_kf_write+0x3a/0x50
[] kernfs_fop_write+0xff/0x180
[] __vfs_write+0x37/0x170
[] vfs_write+0xb2/0x1b0
[] SyS_write+0x55/0xc0
[] do_syscall_64+0x67/0x150
[] return_from_SYSCALL_64+0x0/0x6a
[] 0x

(gdb) list *0x81050d60
0x81050d60 is in load_microcode_amd
  (arch/x86/kernel/cpu/microcode/amd.c:616).

Signed-off-by: Shu Wang 
---
 arch/x86/kernel/cpu/microcode/amd.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 21b1857..c6daec4 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -400,9 +400,12 @@ static void update_cache(struct ucode_patch *new_patch)
 
list_for_each_entry(p, _cache, plist) {
if (p->equiv_cpu == new_patch->equiv_cpu) {
-   if (p->patch_id >= new_patch->patch_id)
+   if (p->patch_id >= new_patch->patch_id) {
/* we already have the latest patch */
+   kfree(new_patch->data);
+   kfree(new_patch);
return;
+   }
 
list_replace(>plist, _patch->plist);
kfree(p->data);
-- 
2.5.0



[PATCH] x86/microcode/AMD: fix memleak in update_cache()

2017-07-18 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak. The mem is allocated in
verify_and_add_patch(), passed to update_cache(patch),
and just dropped the reference without free
if (p->patch_id >= new_patch->patch_id)
return;

unreferenced object 0x88010e780b40 (size 32):
  comm "bash", pid 860, jiffies 4294690939 (age 29.297s)
  backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_trace+0xca/0x1d0
[] load_microcode_amd.isra.0+0x1d0/0x400
[] request_microcode_amd+0xc3/0x160
[] reload_store+0xe1/0x170
[] dev_attr_store+0x18/0x30
[] sysfs_kf_write+0x3a/0x50
[] kernfs_fop_write+0xff/0x180
[] __vfs_write+0x37/0x170
[] vfs_write+0xb2/0x1b0
[] SyS_write+0x55/0xc0
[] do_syscall_64+0x67/0x150
[] return_from_SYSCALL_64+0x0/0x6a
[] 0x

(gdb) list *0x81050d60
0x81050d60 is in load_microcode_amd
  (arch/x86/kernel/cpu/microcode/amd.c:616).

Signed-off-by: Shu Wang 
---
 arch/x86/kernel/cpu/microcode/amd.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/microcode/amd.c 
b/arch/x86/kernel/cpu/microcode/amd.c
index 21b1857..c6daec4 100644
--- a/arch/x86/kernel/cpu/microcode/amd.c
+++ b/arch/x86/kernel/cpu/microcode/amd.c
@@ -400,9 +400,12 @@ static void update_cache(struct ucode_patch *new_patch)
 
list_for_each_entry(p, _cache, plist) {
if (p->equiv_cpu == new_patch->equiv_cpu) {
-   if (p->patch_id >= new_patch->patch_id)
+   if (p->patch_id >= new_patch->patch_id) {
/* we already have the latest patch */
+   kfree(new_patch->data);
+   kfree(new_patch);
return;
+   }
 
list_replace(>plist, _patch->plist);
kfree(p->data);
-- 
2.5.0



[PATCH] audit: fix memleak in auditd_send_unicast_skb.

2017-07-18 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak report, auditd_send_unicast_skb
did not free skb if rcu_dereference(auditd_conn) returns null.

unreferenced object 0x88082568ce00 (size 256):
comm "auditd", pid 1119, jiffies 4294708499
backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_node+0xcc/0x210
[] __alloc_skb+0x5d/0x290
[] audit_make_reply+0x54/0xd0
[] audit_receive_msg+0x967/0xd70

(gdb) list *audit_receive_msg+0x967
0x8113dff7 is in audit_receive_msg (kernel/audit.c:1133).
1132skb = audit_make_reply(0, AUDIT_REPLACE, 0,
0, , sizeof(pvnr));
---
[] audit_receive+0x52/0xa0
[] netlink_unicast+0x181/0x240
[] netlink_sendmsg+0x2c2/0x3b0
[] sock_sendmsg+0x38/0x50
[] SYSC_sendto+0x102/0x190
[] SyS_sendto+0xe/0x10
[] entry_SYSCALL_64_fastpath+0x1a/0xa5
[] 0x

Signed-off-by: Shu Wang 
---
 kernel/audit.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/audit.c b/kernel/audit.c
index 833267b..6dd5569 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -641,6 +641,7 @@ static int auditd_send_unicast_skb(struct sk_buff *skb)
ac = rcu_dereference(auditd_conn);
if (!ac) {
rcu_read_unlock();
+   kfree_skb(skb);
rc = -ECONNREFUSED;
goto err;
}
-- 
2.5.0



[PATCH] audit: fix memleak in auditd_send_unicast_skb.

2017-07-18 Thread shuwang
From: Shu Wang 

Found this issue by kmemleak report, auditd_send_unicast_skb
did not free skb if rcu_dereference(auditd_conn) returns null.

unreferenced object 0x88082568ce00 (size 256):
comm "auditd", pid 1119, jiffies 4294708499
backtrace:
[] kmemleak_alloc+0x4a/0xa0
[] kmem_cache_alloc_node+0xcc/0x210
[] __alloc_skb+0x5d/0x290
[] audit_make_reply+0x54/0xd0
[] audit_receive_msg+0x967/0xd70

(gdb) list *audit_receive_msg+0x967
0x8113dff7 is in audit_receive_msg (kernel/audit.c:1133).
1132skb = audit_make_reply(0, AUDIT_REPLACE, 0,
0, , sizeof(pvnr));
---
[] audit_receive+0x52/0xa0
[] netlink_unicast+0x181/0x240
[] netlink_sendmsg+0x2c2/0x3b0
[] sock_sendmsg+0x38/0x50
[] SYSC_sendto+0x102/0x190
[] SyS_sendto+0xe/0x10
[] entry_SYSCALL_64_fastpath+0x1a/0xa5
[] 0x

Signed-off-by: Shu Wang 
---
 kernel/audit.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/audit.c b/kernel/audit.c
index 833267b..6dd5569 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -641,6 +641,7 @@ static int auditd_send_unicast_skb(struct sk_buff *skb)
ac = rcu_dereference(auditd_conn);
if (!ac) {
rcu_read_unlock();
+   kfree_skb(skb);
rc = -ECONNREFUSED;
goto err;
}
-- 
2.5.0



[PATCH v2] kmemleak: add oom=<disable|ignore> runtime parameter

2017-07-14 Thread shuwang
From: Shu Wang 

When running memory stress tests, kmemleak could be easily disabled in
function create_object as system is out of memory and kmemleak failed to
alloc from object_cache. Since there's no way to enable kmemleak after
it's off, simply ignore the object_cache alloc failure will just loses
track of some memory objects, but could increase the usability of kmemleak
under memory stress.

The default action for oom is still disable kmemleak,
echo oom=ignore > /sys/kernel/debug/kmemleak can change to action to
ignore oom.

Signed-off-by: Shu Wang 
---
 Documentation/dev-tools/kmemleak.rst |  5 +
 mm/kmemleak.c| 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kmemleak.rst 
b/Documentation/dev-tools/kmemleak.rst
index cb88626..3013809 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -60,6 +60,11 @@ Memory scanning parameters can be modified at run-time by 
writing to the
 or free all kmemleak objects if kmemleak has been disabled.
 - dump=
 dump information about the object found at 
+- oom=disable
+disable kmemleak after system out of memory (default)
+- oom=ignore
+do not disable kmemleak after system out of memory
+(useful for memory stress test, but will lose some objects)
 
 Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
 the kernel command line.
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd8..b5cb2c6 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -236,6 +236,9 @@ static DEFINE_MUTEX(scan_mutex);
 static int kmemleak_skip_disable;
 /* If there are leaks that can be reported */
 static bool kmemleak_found_leaks;
+/* If disable kmemleak after out of memory */
+static bool kmemleak_oom_disable = true;
+
 
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
@@ -556,7 +559,8 @@ static struct kmemleak_object *create_object(unsigned long 
ptr, size_t size,
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
pr_warn("Cannot allocate a kmemleak_object structure\n");
-   kmemleak_disable();
+   if (kmemleak_oom_disable)
+   kmemleak_disable();
return NULL;
}
 
@@ -1888,6 +1892,10 @@ static ssize_t kmemleak_write(struct file *file, const 
char __user *user_buf,
kmemleak_scan();
else if (strncmp(buf, "dump=", 5) == 0)
ret = dump_str_object_info(buf + 5);
+   else if (strncmp(buf, "oom=ignore", 10) == 0)
+   kmemleak_oom_disable = false;
+   else if (strncmp(buf, "oom=disable", 11) == 0)
+   kmemleak_oom_disable = true;
else
ret = -EINVAL;
 
-- 
2.5.0



[PATCH v2] kmemleak: add oom= runtime parameter

2017-07-14 Thread shuwang
From: Shu Wang 

When running memory stress tests, kmemleak could be easily disabled in
function create_object as system is out of memory and kmemleak failed to
alloc from object_cache. Since there's no way to enable kmemleak after
it's off, simply ignore the object_cache alloc failure will just loses
track of some memory objects, but could increase the usability of kmemleak
under memory stress.

The default action for oom is still disable kmemleak,
echo oom=ignore > /sys/kernel/debug/kmemleak can change to action to
ignore oom.

Signed-off-by: Shu Wang 
---
 Documentation/dev-tools/kmemleak.rst |  5 +
 mm/kmemleak.c| 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kmemleak.rst 
b/Documentation/dev-tools/kmemleak.rst
index cb88626..3013809 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -60,6 +60,11 @@ Memory scanning parameters can be modified at run-time by 
writing to the
 or free all kmemleak objects if kmemleak has been disabled.
 - dump=
 dump information about the object found at 
+- oom=disable
+disable kmemleak after system out of memory (default)
+- oom=ignore
+do not disable kmemleak after system out of memory
+(useful for memory stress test, but will lose some objects)
 
 Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
 the kernel command line.
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd8..b5cb2c6 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -236,6 +236,9 @@ static DEFINE_MUTEX(scan_mutex);
 static int kmemleak_skip_disable;
 /* If there are leaks that can be reported */
 static bool kmemleak_found_leaks;
+/* If disable kmemleak after out of memory */
+static bool kmemleak_oom_disable = true;
+
 
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
@@ -556,7 +559,8 @@ static struct kmemleak_object *create_object(unsigned long 
ptr, size_t size,
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
pr_warn("Cannot allocate a kmemleak_object structure\n");
-   kmemleak_disable();
+   if (kmemleak_oom_disable)
+   kmemleak_disable();
return NULL;
}
 
@@ -1888,6 +1892,10 @@ static ssize_t kmemleak_write(struct file *file, const 
char __user *user_buf,
kmemleak_scan();
else if (strncmp(buf, "dump=", 5) == 0)
ret = dump_str_object_info(buf + 5);
+   else if (strncmp(buf, "oom=ignore", 10) == 0)
+   kmemleak_oom_disable = false;
+   else if (strncmp(buf, "oom=disable", 11) == 0)
+   kmemleak_oom_disable = true;
else
ret = -EINVAL;
 
-- 
2.5.0



[PATCH] kmemleak: add oom=<disable|ignore> runtime parameter

2017-07-14 Thread shuwang
From: Shu Wang 

When running memory stress tests, kmemleak could be easily disabled in
function create_object as system is out of memory and kmemleak failed to
alloc from object_cache. Since there's no way to enable kmemleak after
it's off, simply ignore the object_cache alloc failure will just loses
track of some memory objects, but could increase the usability of kmemleak
under memory stress.

The default action for oom is still disable kmemleak,
echo oom=ignore > /sys/kernel/debug/kmemleak can change to action to
ignore oom.

Signed-off-by: Shu Wang 
---
 Documentation/dev-tools/kmemleak.rst |  5 +
 mm/kmemleak.c| 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kmemleak.rst 
b/Documentation/dev-tools/kmemleak.rst
index cb88626..3013809 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -60,6 +60,11 @@ Memory scanning parameters can be modified at run-time by 
writing to the
 or free all kmemleak objects if kmemleak has been disabled.
 - dump=
 dump information about the object found at 
+- oom=disable
+disable kmemleak after system out of memory (default)
+- oom=ignore
+do not disable kmemleak after system out of memory
+(useful for memory stress test, but will lose some objects)
 
 Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
 the kernel command line.
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd8..a58080f 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -236,6 +236,9 @@ static DEFINE_MUTEX(scan_mutex);
 static int kmemleak_skip_disable;
 /* If there are leaks that can be reported */
 static bool kmemleak_found_leaks;
+/* If disable kmemleak after out of memory */
+static bool kmemleak_oom_disable = true;
+
 
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
@@ -556,7 +559,8 @@ static struct kmemleak_object *create_object(unsigned long 
ptr, size_t size,
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
pr_warn("Cannot allocate a kmemleak_object structure\n");
-   kmemleak_disable();
+   if (kmemleak_oom_disable)
+   kmemleak_disable();
return NULL;
}
 
@@ -1888,6 +1892,10 @@ static ssize_t kmemleak_write(struct file *file, const 
char __user *user_buf,
kmemleak_scan();
else if (strncmp(buf, "dump=", 5) == 0)
ret = dump_str_object_info(buf + 5);
+   else if (strncmp(buf, "oom=ignore", 10))
+   kmemleak_oom_disable = false;
+   else if (strncmp(buf, "oom=disable", 11))
+   kmemleak_oom_disable = true;
else
ret = -EINVAL;
 
-- 
2.5.0



[PATCH] kmemleak: add oom= runtime parameter

2017-07-14 Thread shuwang
From: Shu Wang 

When running memory stress tests, kmemleak could be easily disabled in
function create_object as system is out of memory and kmemleak failed to
alloc from object_cache. Since there's no way to enable kmemleak after
it's off, simply ignore the object_cache alloc failure will just loses
track of some memory objects, but could increase the usability of kmemleak
under memory stress.

The default action for oom is still disable kmemleak,
echo oom=ignore > /sys/kernel/debug/kmemleak can change to action to
ignore oom.

Signed-off-by: Shu Wang 
---
 Documentation/dev-tools/kmemleak.rst |  5 +
 mm/kmemleak.c| 10 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/Documentation/dev-tools/kmemleak.rst 
b/Documentation/dev-tools/kmemleak.rst
index cb88626..3013809 100644
--- a/Documentation/dev-tools/kmemleak.rst
+++ b/Documentation/dev-tools/kmemleak.rst
@@ -60,6 +60,11 @@ Memory scanning parameters can be modified at run-time by 
writing to the
 or free all kmemleak objects if kmemleak has been disabled.
 - dump=
 dump information about the object found at 
+- oom=disable
+disable kmemleak after system out of memory (default)
+- oom=ignore
+do not disable kmemleak after system out of memory
+(useful for memory stress test, but will lose some objects)
 
 Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
 the kernel command line.
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd8..a58080f 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -236,6 +236,9 @@ static DEFINE_MUTEX(scan_mutex);
 static int kmemleak_skip_disable;
 /* If there are leaks that can be reported */
 static bool kmemleak_found_leaks;
+/* If disable kmemleak after out of memory */
+static bool kmemleak_oom_disable = true;
+
 
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
@@ -556,7 +559,8 @@ static struct kmemleak_object *create_object(unsigned long 
ptr, size_t size,
object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
if (!object) {
pr_warn("Cannot allocate a kmemleak_object structure\n");
-   kmemleak_disable();
+   if (kmemleak_oom_disable)
+   kmemleak_disable();
return NULL;
}
 
@@ -1888,6 +1892,10 @@ static ssize_t kmemleak_write(struct file *file, const 
char __user *user_buf,
kmemleak_scan();
else if (strncmp(buf, "dump=", 5) == 0)
ret = dump_str_object_info(buf + 5);
+   else if (strncmp(buf, "oom=ignore", 10))
+   kmemleak_oom_disable = false;
+   else if (strncmp(buf, "oom=disable", 11))
+   kmemleak_oom_disable = true;
else
ret = -EINVAL;
 
-- 
2.5.0