From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933822AbbGGVXr (ORCPT ); Tue, 7 Jul 2015 17:23:47 -0400 Received: from mga09.intel.com ([134.134.136.24]:45935 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932946AbbGGVXi (ORCPT ); Tue, 7 Jul 2015 17:23:38 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,426,1432623600"; d="scan'208";a="757841026" From: Tomas Winkler To: Greg Kroah-Hartman , Linus Torvalds Cc: arnd@arndb.de, Alexander Usyskin , linux-kernel@vger.kernel.org, Tomas Winkler , Samuel Ortiz Subject: [char-misc 4.2] mei: nfc: fix deadlock on shutdown/suspend path Date: Wed, 8 Jul 2015 00:22:03 +0300 Message-Id: <1436304123-7501-1-git-send-email-tomas.winkler@intel.com> X-Mailer: git-send-email 2.4.3 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In function mei_nfc_host_exit mei_cl_remove_device cannot be called under the device mutex as device removing flow invokes the device driver remove handler that calls in turn to mei_cl_disable_device which naturally acquires the device mutex. Also remove mei_cl_bus_remove_devices which has the same issue, but is never executed as currently the only device on the mei client bus is NFC and a new device cannot be easily added till the bus revamp is completed. This fixes regression caused by commit be9b720a0ccba096d669bc86634f900b82b9bf71 Author: Tomas Winkler Date: Thu May 7 15:54:04 2015 +0300 NFC: mei_phy: move all nfc logic from mei driver to nfc Prior to this change the nfc driver remove handler called to no-op disable function while actual nfc device was disabled directly from the mei driver. Reported-by: Linus Torvalds Cc: Samuel Ortiz Signed-off-by: Tomas Winkler --- drivers/misc/mei/bus.c | 16 ---------------- drivers/misc/mei/init.c | 2 -- drivers/misc/mei/nfc.c | 3 ++- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 357b6ae4d207..458aa5a09c52 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -552,22 +552,6 @@ void mei_cl_bus_rx_event(struct mei_cl *cl) schedule_work(&device->event_work); } -void mei_cl_bus_remove_devices(struct mei_device *dev) -{ - struct mei_cl *cl, *next; - - mutex_lock(&dev->device_lock); - list_for_each_entry_safe(cl, next, &dev->device_list, device_link) { - if (cl->device) - mei_cl_remove_device(cl->device); - - list_del(&cl->device_link); - mei_cl_unlink(cl); - kfree(cl); - } - mutex_unlock(&dev->device_lock); -} - int __init mei_cl_bus_init(void) { return bus_register(&mei_cl_bus_type); diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 94514b2c7a50..00c3865ca3b1 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -333,8 +333,6 @@ void mei_stop(struct mei_device *dev) mei_nfc_host_exit(dev); - mei_cl_bus_remove_devices(dev); - mutex_lock(&dev->device_lock); mei_wd_stop(dev); diff --git a/drivers/misc/mei/nfc.c b/drivers/misc/mei/nfc.c index b983c4ecad38..290ef3037437 100644 --- a/drivers/misc/mei/nfc.c +++ b/drivers/misc/mei/nfc.c @@ -402,11 +402,12 @@ void mei_nfc_host_exit(struct mei_device *dev) cldev->priv_data = NULL; - mutex_lock(&dev->device_lock); /* Need to remove the device here * since mei_nfc_free will unlink the clients */ mei_cl_remove_device(cldev); + + mutex_lock(&dev->device_lock); mei_nfc_free(ndev); mutex_unlock(&dev->device_lock); } -- 2.4.3