From 30c54df7cb9b15b222529a028390b9c9582dd65e Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 27 Jan 2014 22:27:23 +0200 Subject: mei: clear write cb from waiting list on reset Clear write callbacks sitting in write_waiting list on reset. Otherwise these callbacks are left dangling and cause memory leak. Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 1ee2b9492a8..ccdacb5fcd8 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -942,8 +942,16 @@ void mei_cl_all_wakeup(struct mei_device *dev) void mei_cl_all_write_clear(struct mei_device *dev) { struct mei_cl_cb *cb, *next; + struct list_head *list; - list_for_each_entry_safe(cb, next, &dev->write_list.list, list) { + list = &dev->write_list.list; + list_for_each_entry_safe(cb, next, list, list) { + list_del(&cb->list); + mei_io_cb_free(cb); + } + + list = &dev->write_waiting_list.list; + list_for_each_entry_safe(cb, next, list, list) { list_del(&cb->list); mei_io_cb_free(cb); } -- cgit v1.2.3-70-g09d2 From 5cb906c7035f03a3a44fecece9d3ff8fcc75d6e0 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Mon, 27 Jan 2014 22:27:24 +0200 Subject: mei: don't unset read cb ptr on reset Don't set read callback to NULL during reset as this leads to memory leak of both cb and its buffer. The memory is correctly freed during mei_release. The memory leak is detectable by kmemleak if application has open read call while system is going through suspend/resume. unreferenced object 0xecead780 (size 64): comm "AsyncTask #1", pid 1018, jiffies 4294949621 (age 152.440s) hex dump (first 32 bytes): 00 01 10 00 00 02 20 00 00 bf 30 f1 00 00 00 00 ...... ...0..... 00 00 00 00 00 00 00 00 36 01 00 00 00 70 da e2 ........6....p.. backtrace: [] kmemleak_alloc+0x3c/0xa0 [] kmem_cache_alloc_trace+0xc6/0x190 [] mei_io_cb_init+0x29/0x50 [] mei_cl_read_start+0x102/0x360 [] mei_read+0x103/0x4e0 [] vfs_read+0x89/0x160 [] SyS_read+0x4f/0x80 [] syscall_call+0x7/0xb [] 0xffffffff unreferenced object 0xe2da7000 (size 512): comm "AsyncTask #1", pid 1018, jiffies 4294949621 (age 152.440s) hex dump (first 32 bytes): 00 6c da e2 7c 00 00 00 00 00 00 00 c0 eb 0c 59 .l..|..........Y 1b 00 00 00 01 00 00 00 02 10 00 00 01 00 00 00 ................ backtrace: [] kmemleak_alloc+0x3c/0xa0 [] __kmalloc+0xe7/0x1d0 [] mei_io_cb_alloc_resp_buf+0x2e/0x60 [] mei_cl_read_start+0x12c/0x360 [] mei_read+0x103/0x4e0 [] vfs_read+0x89/0x160 [] SyS_read+0x4f/0x80 [] syscall_call+0x7/0xb [] 0xffffffff Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/client.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/misc/mei/client.c') diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index ccdacb5fcd8..9b809cfc289 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -908,7 +908,6 @@ void mei_cl_all_disconnect(struct mei_device *dev) list_for_each_entry_safe(cl, next, &dev->file_list, link) { cl->state = MEI_FILE_DISCONNECTED; cl->mei_flow_ctrl_creds = 0; - cl->read_cb = NULL; cl->timer_count = 0; } } -- cgit v1.2.3-70-g09d2