Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030710AbbD1RrQ (ORCPT ); Tue, 28 Apr 2015 13:47:16 -0400 Received: from mail-bn1bon0110.outbound.protection.outlook.com ([157.56.111.110]:8811 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1030492AbbD1RrN (ORCPT ); Tue, 28 Apr 2015 13:47:13 -0400 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; From: "J. German Rivera" To: , , , CC: , , , , , , , , , "J. German Rivera" Subject: [PATCH 6/7] staging: fsl-mc: Add locking to serialize mc_send_command() calls Date: Tue, 28 Apr 2015 12:39:09 -0500 Message-ID: <1430242750-17745-7-git-send-email-German.Rivera@freescale.com> X-Mailer: git-send-email 2.3.3 In-Reply-To: <1430242750-17745-1-git-send-email-German.Rivera@freescale.com> References: <1430242750-17745-1-git-send-email-German.Rivera@freescale.com> X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.158.2;CTRY:US;IPV:NLI;EFV:NLI;BMV:1;SFV:NSPM;SFS:(10019020)(6009001)(339900001)(279900001)(199003)(189002)(104016003)(48376002)(5001770100001)(87936001)(36756003)(19625305001)(77156002)(50466002)(76176999)(6806004)(229853001)(92566002)(2201001)(46102003)(62966003)(50986999)(19580395003)(575784001)(19580405001)(86362001)(106466001)(85426001)(50226001)(15975445007)(2950100001)(47776003)(77096005)(105606002)(4001430100001);DIR:OUT;SFP:1102;SCL:1;SRVR:CY1PR0301MB1241;H:az84smr01.freescale.net;FPR:;SPF:Fail;MLV:sfv;A:1;MX:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB1241; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5002010)(5005006)(3002001);SRVR:CY1PR0301MB1241;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB1241; X-Forefront-PRVS: 0560A2214D X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Apr 2015 17:47:09.3581 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d;Ip=[192.88.158.2];Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR0301MB1241 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5367 Lines: 154 Add a locking mechanism to serialize mc_send_command() calls that use the same fsl_mc_io object (same MC portal). All mc_send_command() calls with the same fsl_m_io object have to be either from non-atomic context or from atomic context, but not both. When the fsl_mc_io object is created the owner needs to know in which type of context the fsl_mc_io object is going to be used. A flag passed-in to fsl_create_mc_io() will indicate whether the fsl_mc_io object will be used in atomic or non-atomic context. If the fsl_mc_io object is going to be used in non-atomic context, mc_send_command() calls with it will be serialized using a mutex. Otherwise, if the fsl_mc_io object is going to be used in atomic context, mc_semd_command() calls with it will be serialized using a spinlock. Signed-off-by: J. German Rivera Change-Id: Icb770cd36e204ee6a17ad0f81e1d31cc9fe96816 Reviewed-on: http://git.am.freescale.net:8181/34876 Tested-by: Review Code-CDREVIEW Reviewed-by: Stuart Yoder --- drivers/staging/fsl-mc/bus/mc-sys.c | 36 ++++++++++++++++++++++++++++----- drivers/staging/fsl-mc/include/mc-sys.h | 23 +++++++++++++++++++-- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/drivers/staging/fsl-mc/bus/mc-sys.c b/drivers/staging/fsl-mc/bus/mc-sys.c index 9ae000c..1679054 100644 --- a/drivers/staging/fsl-mc/bus/mc-sys.c +++ b/drivers/staging/fsl-mc/bus/mc-sys.c @@ -86,6 +86,11 @@ int __must_check fsl_create_mc_io(struct device *dev, mc_io->portal_phys_addr = mc_portal_phys_addr; mc_io->portal_size = mc_portal_size; mc_io->resource = resource; + if (flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL) + spin_lock_init(&mc_io->spinlock); + else + mutex_init(&mc_io->mutex); + res = devm_request_mem_region(dev, mc_portal_phys_addr, mc_portal_size, @@ -230,15 +235,26 @@ static inline enum mc_cmd_status mc_read_response(struct mc_command __iomem * * @cmd: command to be sent * * Returns '0' on Success; Error code otherwise. - * - * NOTE: This function cannot be invoked from from atomic contexts. */ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) { + int error; enum mc_cmd_status status; unsigned long jiffies_until_timeout = jiffies + MC_CMD_COMPLETION_TIMEOUT_JIFFIES; + if (preemptible()) { + if (WARN_ON(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL)) + return -EINVAL; + + mutex_lock(&mc_io->mutex); + } else { + if (WARN_ON(!(mc_io->flags & FSL_MC_IO_ATOMIC_CONTEXT_PORTAL))) + return -EINVAL; + + spin_lock(&mc_io->spinlock); + } + /* * Send command to the MC hardware: */ @@ -269,7 +285,8 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) (unsigned int) MC_CMD_HDR_READ_CMDID(cmd->header)); - return -ETIMEDOUT; + error = -ETIMEDOUT; + goto common_exit; } } @@ -281,9 +298,18 @@ int mc_send_command(struct fsl_mc_io *mc_io, struct mc_command *cmd) mc_status_to_string(status), (unsigned int)status); - return mc_status_to_error(status); + error = mc_status_to_error(status); + goto common_exit; } - return 0; + error = 0; + +common_exit: + if (preemptible()) + mutex_unlock(&mc_io->mutex); + else + spin_unlock(&mc_io->spinlock); + + return error; } EXPORT_SYMBOL(mc_send_command); diff --git a/drivers/staging/fsl-mc/include/mc-sys.h b/drivers/staging/fsl-mc/include/mc-sys.h index cb3b5a2..24e51f7 100644 --- a/drivers/staging/fsl-mc/include/mc-sys.h +++ b/drivers/staging/fsl-mc/include/mc-sys.h @@ -39,6 +39,13 @@ #include #include #include +#include +#include + +/** + * Bit masks for a MC I/O object (struct fsl_mc_io) flags + */ +#define FSL_MC_IO_ATOMIC_CONTEXT_PORTAL 0x0001 struct fsl_mc_resource; struct mc_command; @@ -53,14 +60,26 @@ struct mc_command; * @resource: generic resource associated with the MC portal if * the MC portal came from a resource pool, or NULL if the MC portal * is permanently bound to a device (e.g., a DPRC) + * @mutex: Mutex to serialize mc_send_command() calls that use the same MC + * portal, if the fsl_mc_io object was created with the + * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag off. mc_send_command() calls for this + * fsl_mc_io object must be made only from non-atomic context. + * @spinlock: Spinlock to serialize mc_send_command() calls that use the same MC + * portal, if the fsl_mc_io object was created with the + * FSL_MC_IO_ATOMIC_CONTEXT_PORTAL flag on. mc_send_command() calls for this + * fsl_mc_io object must be made only from atomic context. */ struct fsl_mc_io { struct device *dev; - uint32_t flags; - uint32_t portal_size; + uint16_t flags; + uint16_t portal_size; phys_addr_t portal_phys_addr; void __iomem *portal_virt_addr; struct fsl_mc_resource *resource; + union { + struct mutex mutex; /* serializes mc_send_command() calls */ + spinlock_t spinlock; /* serializes mc_send_command() calls */ + }; }; int __must_check fsl_create_mc_io(struct device *dev, -- 2.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/