From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751331AbcBEX2V (ORCPT ); Fri, 5 Feb 2016 18:28:21 -0500 Received: from mxout1.idt.com ([157.165.5.25]:40099 "EHLO mxout1.idt.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751246AbcBEX2R (ORCPT ); Fri, 5 Feb 2016 18:28:17 -0500 From: Alexandre Bounine To: Andrew Morton Cc: Alexandre Bounine , Matt Porter , Aurelien Jacquiot , Andre van Herk , linux-kernel@vger.kernel.org Subject: [PATCH 19/30] rapidio: add lock protection for doorbell list Date: Fri, 5 Feb 2016 18:19:35 -0500 Message-Id: <1454714386-15259-20-git-send-email-alexandre.bounine@idt.com> X-Mailer: git-send-email 1.7.8.4 In-Reply-To: <1454714386-15259-1-git-send-email-alexandre.bounine@idt.com> References: <1454714386-15259-1-git-send-email-alexandre.bounine@idt.com> X-TM-AS-MML: disable Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add lock protection around doorbell list handling to prevent list corruption on SMP platforms. Signed-off-by: Alexandre Bounine Cc: Matt Porter Cc: Aurelien Jacquiot Cc: Andre van Herk Cc: linux-kernel@vger.kernel.org --- drivers/rapidio/rio.c | 9 ++++++--- include/linux/rio.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 4cee4f8..a2ab58d 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -362,7 +362,9 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res, dbell->dinb = dinb; dbell->dev_id = dev_id; + mutex_lock(&mport->lock); list_add_tail(&dbell->node, &mport->dbells); + mutex_unlock(&mport->lock); out: return rc; @@ -426,12 +428,15 @@ int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end) int rc = 0, found = 0; struct rio_dbell *dbell; + mutex_lock(&mport->lock); list_for_each_entry(dbell, &mport->dbells, node) { if ((dbell->res->start == start) && (dbell->res->end == end)) { + list_del(&dbell->node); found = 1; break; } } + mutex_unlock(&mport->lock); /* If we can't find an exact match, fail */ if (!found) { @@ -439,9 +444,6 @@ int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end) goto out; } - /* Delete from list */ - list_del(&dbell->node); - /* Release the doorbell resource */ rc = release_resource(dbell->res); @@ -2024,6 +2026,7 @@ int rio_mport_initialize(struct rio_mport *mport) mport->id = next_portid++; mport->host_deviceid = rio_get_hdid(mport->id); mport->nscan = NULL; + mutex_init(&mport->lock); return 0; } diff --git a/include/linux/rio.h b/include/linux/rio.h index f4a38b4..fc614c5 100644 --- a/include/linux/rio.h +++ b/include/linux/rio.h @@ -248,6 +248,7 @@ enum rio_phy_type { * @node: Node in global list of master ports * @nnode: Node in network list of master ports * @net: RIO net this mport is attached to + * @mutex lock: lock to synchronize lists manipulations * @iores: I/O mem resource that this master port interface owns * @riores: RIO resources that this master port interfaces owns * @inb_msg: RIO inbound message event descriptors @@ -271,6 +272,7 @@ struct rio_mport { struct list_head node; /* node in global list of ports */ struct list_head nnode; /* node in net list of ports */ struct rio_net *net; /* RIO net this mport is attached to */ + struct mutex lock; /* lock to synchronize lists manipulations */ struct resource iores; struct resource riores[RIO_MAX_MPORT_RESOURCES]; struct rio_msg inb_msg[RIO_MAX_MBOX]; -- 1.7.8.4