From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756469AbcGYWHd (ORCPT ); Mon, 25 Jul 2016 18:07:33 -0400 Received: from mga14.intel.com ([192.55.52.115]:24479 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756329AbcGYWHS (ORCPT ); Mon, 25 Jul 2016 18:07:18 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,421,1464678000"; d="scan'208";a="1013699458" From: Tomas Winkler To: Greg Kroah-Hartman Cc: Alexander Usyskin , linux-kernel@vger.kernel.org, stable@vger.kernel.org#4.6+, Tomas Winkler Subject: [char-misc-next v2 9/9] mei: amthif: fix deadlock in initialization during a reset Date: Tue, 26 Jul 2016 01:06:09 +0300 Message-Id: <1469484369-19214-10-git-send-email-tomas.winkler@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1469484369-19214-1-git-send-email-tomas.winkler@intel.com> References: <1469484369-19214-1-git-send-email-tomas.winkler@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Alexander Usyskin The device lock was unnecessary obtained in bus rescan work before the amthif client search. That causes incorrect lock ordering and task hang: ... [88004.613213] INFO: task kworker/1:14:21832 blocked for more than 120 seconds. ... [88004.645934] Workqueue: events mei_cl_bus_rescan_work ... The correct lock order is cl_bus_lock device_lock me_clients_rwsem Move device_lock into amthif init function that called after me_clients_rwsem is released. This fixes regression introduced by commit: commit 025fb792bac3 ("mei: split amthif client init from end of clients enumeration") Cc: # 4.6+ Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler --- V2: new in the seriese drivers/misc/mei/amthif.c | 12 +++++++++--- drivers/misc/mei/bus.c | 2 -- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 2222b60e9208..082462ea90c9 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -66,8 +66,12 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl) struct mei_cl *cl = &dev->iamthif_cl; int ret; - if (mei_cl_is_connected(cl)) - return 0; + mutex_lock(&dev->device_lock); + + if (mei_cl_is_connected(cl)) { + ret = 0; + goto out; + } dev->iamthif_state = MEI_IAMTHIF_IDLE; @@ -76,11 +80,13 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl) ret = mei_cl_link(cl); if (ret < 0) { dev_err(dev->dev, "amthif: failed cl_link %d\n", ret); - return ret; + goto out; } ret = mei_cl_connect(cl, me_cl, NULL); +out: + mutex_unlock(&dev->device_lock); return ret; } diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index cdf13f6d2697..8cac7ef9ad0d 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -984,12 +984,10 @@ void mei_cl_bus_rescan_work(struct work_struct *work) container_of(work, struct mei_device, bus_rescan_work); struct mei_me_client *me_cl; - mutex_lock(&bus->device_lock); me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid); if (me_cl) mei_amthif_host_init(bus, me_cl); mei_me_cl_put(me_cl); - mutex_unlock(&bus->device_lock); mei_cl_bus_rescan(bus); } -- 2.7.4