From 9280ddb19489fa24e2d4f6f492d185ae1172bec2 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Fri, 13 Jun 2014 17:02:24 +0200 Subject: s390/ccwgroup: obtain extra reference for asynchronous processing Commit 0b60f9ead5d4816e7e3d6e28f4a0d22d4a1b2513 "s390: use device_remove_file_self() instead of device_schedule_callback()" changed ccwgroup to use an extra work queue instead of device_schedule_callback. This function obtained an extra device reference for its async work which is missing in the new implementation and results in a "freeing memory with a lock still held" BUG. Fix this by obtaining an extra reference for the async work. Reported-by: Stefan Raspl Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/ccwgroup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/s390/cio') diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index dfd7bc681c25..040e643746aa 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -227,6 +227,7 @@ static void ccwgroup_ungroup_workfn(struct work_struct *work) container_of(work, struct ccwgroup_device, ungroup_work); ccwgroup_ungroup(gdev); + put_device(&gdev->dev); } static void ccwgroup_release(struct device *dev) @@ -412,8 +413,10 @@ static int ccwgroup_notifier(struct notifier_block *nb, unsigned long action, { struct ccwgroup_device *gdev = to_ccwgroupdev(data); - if (action == BUS_NOTIFY_UNBIND_DRIVER) + if (action == BUS_NOTIFY_UNBIND_DRIVER) { + get_device(&gdev->dev); schedule_work(&gdev->ungroup_work); + } return NOTIFY_OK; } -- cgit v1.2.3-59-g8ed1b