From patchwork Wed Jun 15 12:46:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A12ECCA47F for ; Wed, 15 Jun 2022 12:47:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348480AbiFOMry (ORCPT ); Wed, 15 Jun 2022 08:47:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52968 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348534AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp15.bhosted.nl (smtp15.bhosted.nl [IPv6:2a02:9e0:8000::26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 828CFE017 for ; Wed, 15 Jun 2022 05:47:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=pCfD1n1XsGzmFuTRiNWt50/YhUvtppaL5IsTk3NIMGc=; b=OhlSdw9M5XbBTBbMQSXmidsemFLeYTPxSZk9LFO0K+/rmvTeNpCmiqXpv2+Q7rZYH8ZT6RKO9k8if XeZTCRRclSYREVHvyCp0xjoRQcmS1gGnQr3bXFYzpdn1shldbOdLtcSgUnpBkULce/P9sMv+FyPr6l loSwTuXfbauhFMZSmOrgrC+4iGCF7jG72Bbg6+PzIcbtXNwcSoYIHSp4aC3I+duh8WdSgw3kxWrINk zmfBOkCaAK/1phVdyEzs1w3emBXaJw9rklXX1mDg6mSsGvkCHPJyVAw+pWhg9cWrjp7A5f/pgz8TeZ h1379tgA7CaTMYkYpNu+oq5cmWW7pmQ== X-MSG-ID: 530efc0b-eca9-11ec-ba03-0050569d3a82 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 01/11] spi: Move ctlr->cur_msg_prepared to struct spi_message Date: Wed, 15 Jun 2022 14:46:24 +0200 Message-Id: <20220615124634.3302867-2-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org This enables the possibility to transfer a message that is not at the current tip of the async message queue. This is in preparation of the next patch(es) which enable spi_sync messages to skip the queue altogether. Signed-off-by: David Jander --- drivers/spi/spi.c | 7 ++++--- include/linux/spi/spi.h | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index c78d1ceeaa42..eb6360153fa1 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1684,7 +1684,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) spi_finalize_current_message(ctlr); goto out; } - ctlr->cur_msg_prepared = true; + msg->prepared = true; } ret = spi_map_msg(ctlr, msg); @@ -1926,7 +1926,7 @@ void spi_finalize_current_message(struct spi_controller *ctlr) */ spi_res_release(ctlr, mesg); - if (ctlr->cur_msg_prepared && ctlr->unprepare_message) { + if (mesg->prepared && ctlr->unprepare_message) { ret = ctlr->unprepare_message(ctlr, mesg); if (ret) { dev_err(&ctlr->dev, "failed to unprepare message: %d\n", @@ -1934,9 +1934,10 @@ void spi_finalize_current_message(struct spi_controller *ctlr) } } + mesg->prepared = false; + spin_lock_irqsave(&ctlr->queue_lock, flags); ctlr->cur_msg = NULL; - ctlr->cur_msg_prepared = false; ctlr->fallback = false; kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); spin_unlock_irqrestore(&ctlr->queue_lock, flags); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index c96f526d9a20..1a75c26742f2 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -385,8 +385,6 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @queue: message queue * @idling: the device is entering idle state * @cur_msg: the currently in-flight message - * @cur_msg_prepared: spi_prepare_message was called for the currently - * in-flight message * @cur_msg_mapped: message has been mapped for DMA * @last_cs: the last chip_select that is recorded by set_cs, -1 on non chip * selected @@ -621,7 +619,6 @@ struct spi_controller { bool running; bool rt; bool auto_runtime_pm; - bool cur_msg_prepared; bool cur_msg_mapped; char last_cs; bool last_cs_mode_high; @@ -988,6 +985,7 @@ struct spi_transfer { * @queue: for use by whichever driver currently owns the message * @state: for use by whichever driver currently owns the message * @resources: for resource management when the spi message is processed + * @prepared: spi_prepare_message was called for the this message * * A @spi_message is used to execute an atomic sequence of data transfers, * each represented by a struct spi_transfer. The sequence is "atomic" @@ -1037,6 +1035,9 @@ struct spi_message { /* list of spi_res reources when the spi message is processed */ struct list_head resources; + + /* spi_prepare_message was called for this message */ + bool prepared; }; static inline void spi_message_init_no_memset(struct spi_message *m) From patchwork Wed Jun 15 12:46:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882292 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0765FC433EF for ; Wed, 15 Jun 2022 12:47:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347021AbiFOMry (ORCPT ); Wed, 15 Jun 2022 08:47:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348532AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 823C6DFA4 for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=gLZK2265Pd0i7MErC6G690atwVBOD3ajBYmbAdqlGCc=; b=eTLfBuH4CheR/YEN5HHPus84YF9l7h8U5v03qbJwYNib3VnsNZ6MaCwkrywcd+FM5LEFCcyH+UZyg uvgWNdDL5+n3upnLLWPh+nnum9BNR/WZQldmta1P8cXeQZc2xVvUo0KSBp4YaYpbzAuPK60kOYJJGP WPcBuLKMI1JJG6tKs2b524X+i0To0lTX2CdG0C6hesRnJ7ii9QyctbHUQbCwWMLH6IGEnERxJf3uvc Y7tfwYezmZ3ZDN7X+fmEFp6dIbAvzL8lz+Gvj0hbi6eTvQ0gIkfE3LcneG6q4hTgX1pSN9D67iP7Ax yviPKEgBhV+khndBYKew5ZnrXV0Kr1A== X-MSG-ID: 531b0b56-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [FRC] [PATCH v2 02/11] spi: Don't use the message queue if possible in spi_sync Date: Wed, 15 Jun 2022 14:46:25 +0200 Message-Id: <20220615124634.3302867-3-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org The interaction with the controller message queue and its corresponding auxiliary flags and variables requires the use of the queue_lock which is costly. Since spi_sync will transfer the complete message anyway, and not return until it is finished, there is no need to put the message into the queue if the queue is empty. This can save a lot of overhead. As an example of how significant this is, when using the MCP2518FD SPI CAN controller on a i.MX8MM SoC, the time during which the interrupt line stays active (during 3 relatively short spi_sync messages), is reduced from 98us to 72us by this patch. Signed-off-by: David Jander --- drivers/spi/spi.c | 246 ++++++++++++++++++++++++---------------- include/linux/spi/spi.h | 11 +- 2 files changed, 159 insertions(+), 98 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index eb6360153fa1..2d057d03c4f7 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1549,6 +1549,80 @@ static void spi_idle_runtime_pm(struct spi_controller *ctlr) } } +static int __spi_pump_transfer_message(struct spi_controller *ctlr, + struct spi_message *msg, bool was_busy) +{ + struct spi_transfer *xfer; + int ret; + + if (!was_busy && ctlr->auto_runtime_pm) { + ret = pm_runtime_get_sync(ctlr->dev.parent); + if (ret < 0) { + pm_runtime_put_noidle(ctlr->dev.parent); + dev_err(&ctlr->dev, "Failed to power device: %d\n", + ret); + return ret; + } + } + + if (!was_busy) + trace_spi_controller_busy(ctlr); + + if (!was_busy && ctlr->prepare_transfer_hardware) { + ret = ctlr->prepare_transfer_hardware(ctlr); + if (ret) { + dev_err(&ctlr->dev, + "failed to prepare transfer hardware: %d\n", + ret); + + if (ctlr->auto_runtime_pm) + pm_runtime_put(ctlr->dev.parent); + + msg->status = ret; + spi_finalize_current_message(ctlr); + + return ret; + } + } + + trace_spi_message_start(msg); + + if (ctlr->prepare_message) { + ret = ctlr->prepare_message(ctlr, msg); + if (ret) { + dev_err(&ctlr->dev, "failed to prepare message: %d\n", + ret); + msg->status = ret; + spi_finalize_current_message(ctlr); + return ret; + } + msg->prepared = true; + } + + ret = spi_map_msg(ctlr, msg); + if (ret) { + msg->status = ret; + spi_finalize_current_message(ctlr); + return ret; + } + + if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) { + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + xfer->ptp_sts_word_pre = 0; + ptp_read_system_prets(xfer->ptp_sts); + } + } + + ret = ctlr->transfer_one_message(ctlr, msg); + if (ret) { + dev_err(&ctlr->dev, + "failed to transfer one message from queue\n"); + return ret; + } + + return 0; +} + /** * __spi_pump_messages - function which processes spi message queue * @ctlr: controller to process queue for @@ -1564,7 +1638,6 @@ static void spi_idle_runtime_pm(struct spi_controller *ctlr) */ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) { - struct spi_transfer *xfer; struct spi_message *msg; bool was_busy = false; unsigned long flags; @@ -1599,6 +1672,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) !ctlr->unprepare_transfer_hardware) { spi_idle_runtime_pm(ctlr); ctlr->busy = false; + ctlr->queue_empty = true; trace_spi_controller_idle(ctlr); } else { kthread_queue_work(ctlr->kworker, @@ -1625,6 +1699,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) spin_lock_irqsave(&ctlr->queue_lock, flags); ctlr->idling = false; + ctlr->queue_empty = true; spin_unlock_irqrestore(&ctlr->queue_lock, flags); return; } @@ -1641,75 +1716,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) spin_unlock_irqrestore(&ctlr->queue_lock, flags); mutex_lock(&ctlr->io_mutex); - - if (!was_busy && ctlr->auto_runtime_pm) { - ret = pm_runtime_resume_and_get(ctlr->dev.parent); - if (ret < 0) { - dev_err(&ctlr->dev, "Failed to power device: %d\n", - ret); - mutex_unlock(&ctlr->io_mutex); - return; - } - } - - if (!was_busy) - trace_spi_controller_busy(ctlr); - - if (!was_busy && ctlr->prepare_transfer_hardware) { - ret = ctlr->prepare_transfer_hardware(ctlr); - if (ret) { - dev_err(&ctlr->dev, - "failed to prepare transfer hardware: %d\n", - ret); - - if (ctlr->auto_runtime_pm) - pm_runtime_put(ctlr->dev.parent); - - msg->status = ret; - spi_finalize_current_message(ctlr); - - mutex_unlock(&ctlr->io_mutex); - return; - } - } - - trace_spi_message_start(msg); - - if (ctlr->prepare_message) { - ret = ctlr->prepare_message(ctlr, msg); - if (ret) { - dev_err(&ctlr->dev, "failed to prepare message: %d\n", - ret); - msg->status = ret; - spi_finalize_current_message(ctlr); - goto out; - } - msg->prepared = true; - } - - ret = spi_map_msg(ctlr, msg); - if (ret) { - msg->status = ret; - spi_finalize_current_message(ctlr); - goto out; - } - - if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) { - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - xfer->ptp_sts_word_pre = 0; - ptp_read_system_prets(xfer->ptp_sts); - } - } - - ret = ctlr->transfer_one_message(ctlr, msg); - if (ret) { - dev_err(&ctlr->dev, - "failed to transfer one message from queue: %d\n", - ret); - goto out; - } - -out: + ret = __spi_pump_transfer_message(ctlr, msg, was_busy); mutex_unlock(&ctlr->io_mutex); /* Prod the scheduler in case transfer_one() was busy waiting */ @@ -1839,6 +1846,7 @@ static int spi_init_queue(struct spi_controller *ctlr) { ctlr->running = false; ctlr->busy = false; + ctlr->queue_empty = true; ctlr->kworker = kthread_create_worker(0, dev_name(&ctlr->dev)); if (IS_ERR(ctlr->kworker)) { @@ -1936,11 +1944,20 @@ void spi_finalize_current_message(struct spi_controller *ctlr) mesg->prepared = false; - spin_lock_irqsave(&ctlr->queue_lock, flags); - ctlr->cur_msg = NULL; - ctlr->fallback = false; - kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); - spin_unlock_irqrestore(&ctlr->queue_lock, flags); + if (!mesg->sync) { + /* + * This message was sent via the async message queue. Handle + * the queue and kick the worker thread to do the + * idling/shutdown or send the next message if needed. + */ + spin_lock_irqsave(&ctlr->queue_lock, flags); + WARN(ctlr->cur_msg != mesg, + "Finalizing queued message that is not the current head of queue!"); + ctlr->cur_msg = NULL; + ctlr->fallback = false; + kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); + spin_unlock_irqrestore(&ctlr->queue_lock, flags); + } trace_spi_message_done(mesg); @@ -2043,6 +2060,7 @@ static int __spi_queued_transfer(struct spi_device *spi, msg->status = -EINPROGRESS; list_add_tail(&msg->queue, &ctlr->queue); + ctlr->queue_empty = false; if (!ctlr->busy && need_pump) kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); @@ -3938,6 +3956,39 @@ static int spi_async_locked(struct spi_device *spi, struct spi_message *message) } +static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct spi_message *msg) +{ + bool was_busy; + int ret; + + mutex_lock(&ctlr->io_mutex); + + /* If another context is idling the device then wait */ + while (ctlr->idling) + usleep_range(10000, 11000); + + was_busy = READ_ONCE(ctlr->busy); + + ret = __spi_pump_transfer_message(ctlr, msg, was_busy); + if (ret) + goto out; + + if (!was_busy) { + kfree(ctlr->dummy_rx); + ctlr->dummy_rx = NULL; + kfree(ctlr->dummy_tx); + ctlr->dummy_tx = NULL; + if (ctlr->unprepare_transfer_hardware && + ctlr->unprepare_transfer_hardware(ctlr)) + dev_err(&ctlr->dev, + "failed to unprepare transfer hardware\n"); + spi_idle_runtime_pm(ctlr); + } + +out: + mutex_unlock(&ctlr->io_mutex); +} + /*-------------------------------------------------------------------------*/ /* @@ -3956,51 +4007,52 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) DECLARE_COMPLETION_ONSTACK(done); int status; struct spi_controller *ctlr = spi->controller; - unsigned long flags; status = __spi_validate(spi, message); if (status != 0) return status; - message->complete = spi_complete; - message->context = &done; message->spi = spi; SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, spi_sync); SPI_STATISTICS_INCREMENT_FIELD(spi->pcpu_statistics, spi_sync); /* - * If we're not using the legacy transfer method then we will - * try to transfer in the calling context so special case. - * This code would be less tricky if we could remove the - * support for driver implemented message queues. + * Checking queue_empty here only guarantees async/sync message + * ordering when coming from the same context. It does not need to + * guard against reentrancy from a different context. The io_mutex + * will catch those cases. */ - if (ctlr->transfer == spi_queued_transfer) { - spin_lock_irqsave(&ctlr->bus_lock_spinlock, flags); + if (READ_ONCE(ctlr->queue_empty)) { + message->sync = true; + message->actual_length = 0; + message->status = -EINPROGRESS; trace_spi_message_submit(message); - status = __spi_queued_transfer(spi, message, false); + SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, spi_sync_immediate); + SPI_STATISTICS_INCREMENT_FIELD(spi->pcpu_statistics, spi_sync_immediate); - spin_unlock_irqrestore(&ctlr->bus_lock_spinlock, flags); - } else { - status = spi_async_locked(spi, message); + __spi_transfer_message_noqueue(ctlr, message); + + return message->status; } + /* + * There are messages in the async queue that could have originated + * from the same context, so we need to preserve ordering. + * Therefor we send the message to the async queue and wait until they + * are completed. + */ + message->complete = spi_complete; + message->context = &done; + status = spi_async_locked(spi, message); if (status == 0) { - /* Push out the messages in the calling context if we can */ - if (ctlr->transfer == spi_queued_transfer) { - SPI_STATISTICS_INCREMENT_FIELD(ctlr->pcpu_statistics, - spi_sync_immediate); - SPI_STATISTICS_INCREMENT_FIELD(spi->pcpu_statistics, - spi_sync_immediate); - __spi_pump_messages(ctlr, false); - } - wait_for_completion(&done); status = message->status; } message->context = NULL; + return status; } diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 1a75c26742f2..74261a83b5fa 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -461,6 +461,8 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @irq_flags: Interrupt enable state during PTP system timestamping * @fallback: fallback to pio if dma transfer return failure with * SPI_TRANS_FAIL_NO_START. + * @queue_empty: signal green light for opportunistically skipping the queue + * for spi_sync transfers. * * Each SPI controller can communicate with one or more @spi_device * children. These make a small bus, sharing MOSI, MISO and SCK signals @@ -677,6 +679,9 @@ struct spi_controller { /* Interrupt enable state during PTP system timestamping */ unsigned long irq_flags; + + /* Flag for enabling opportunistic skipping of the queue in spi_sync */ + bool queue_empty; }; static inline void *spi_controller_get_devdata(struct spi_controller *ctlr) @@ -986,6 +991,7 @@ struct spi_transfer { * @state: for use by whichever driver currently owns the message * @resources: for resource management when the spi message is processed * @prepared: spi_prepare_message was called for the this message + * @sync: this message took the direct sync path skipping the async queue * * A @spi_message is used to execute an atomic sequence of data transfers, * each represented by a struct spi_transfer. The sequence is "atomic" @@ -1037,7 +1043,10 @@ struct spi_message { struct list_head resources; /* spi_prepare_message was called for this message */ - bool prepared; + bool prepared; + + /* this message is skipping the async queue */ + bool sync; }; static inline void spi_message_init_no_memset(struct spi_message *m) From patchwork Wed Jun 15 12:46:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882286 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1C75C433EF for ; Wed, 15 Jun 2022 12:47:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347058AbiFOMrw (ORCPT ); Wed, 15 Jun 2022 08:47:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240141AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp28.bhosted.nl (smtp28.bhosted.nl [IPv6:2a02:9e0:8000::40]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DF133CE3F for ; Wed, 15 Jun 2022 05:47:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=H4ti9M99B6lVzGb3ljKte2Ib95Nd6XVISFe9+7VW/Zk=; b=csPsaBko5bqW0jnrIaHfKi3+Z5DJAZ8WbhODSg9hG9pCzfdJ01wrdO4sQDT2lCNvq8654L0m+CZbv 4UEULy56FxWQjBKwaX/K7dNKeaoEPE6qyDT0NOgmTd/54a4hVQytsBU4V0G6Yxsb7+6ORUU9pCgKJU 5Vhn38fiEJxz4fAYjzMi1mHlTeuYLQGBAQbPi6PQh+7JrrRPX5rwaRcMmaeSM8VIK/eNP41OKuIa34 gsNQPstMugQVhWdVMXlYcUgPQW/tXaBViJjudEL+E+gKt5AKjxNfHOVube2HNaI9i44A0812h7yjkK yEvcQRd/c1OymRWNYHpf90V23Fz2Qcw== X-MSG-ID: 532cb81f-eca9-11ec-8a45-0050569d11ae From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 03/11] spi: Lock controller idling transition inside the io_mutex Date: Wed, 15 Jun 2022 14:46:26 +0200 Message-Id: <20220615124634.3302867-4-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org This way, the spi sync path does not need to deal with the idling transition. Signed-off-by: David Jander --- drivers/spi/spi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2d057d03c4f7..cfff2ff96fa0 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1643,27 +1643,30 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) unsigned long flags; int ret; + /* Take the IO mutex */ + mutex_lock(&ctlr->io_mutex); + /* Lock queue */ spin_lock_irqsave(&ctlr->queue_lock, flags); /* Make sure we are not already running a message */ if (ctlr->cur_msg) { spin_unlock_irqrestore(&ctlr->queue_lock, flags); - return; + goto out_unlock; } /* If another context is idling the device then defer */ if (ctlr->idling) { kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); spin_unlock_irqrestore(&ctlr->queue_lock, flags); - return; + goto out_unlock; } /* Check if the queue is idle */ if (list_empty(&ctlr->queue) || !ctlr->running) { if (!ctlr->busy) { spin_unlock_irqrestore(&ctlr->queue_lock, flags); - return; + goto out_unlock; } /* Defer any non-atomic teardown to the thread */ @@ -1679,7 +1682,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) &ctlr->pump_messages); } spin_unlock_irqrestore(&ctlr->queue_lock, flags); - return; + goto out_unlock; } ctlr->busy = false; @@ -1701,7 +1704,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) ctlr->idling = false; ctlr->queue_empty = true; spin_unlock_irqrestore(&ctlr->queue_lock, flags); - return; + goto out_unlock; } /* Extract head of queue */ @@ -1715,13 +1718,16 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) ctlr->busy = true; spin_unlock_irqrestore(&ctlr->queue_lock, flags); - mutex_lock(&ctlr->io_mutex); ret = __spi_pump_transfer_message(ctlr, msg, was_busy); mutex_unlock(&ctlr->io_mutex); /* Prod the scheduler in case transfer_one() was busy waiting */ if (!ret) cond_resched(); + return; + +out_unlock: + mutex_unlock(&ctlr->io_mutex); } /** From patchwork Wed Jun 15 12:46:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882288 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DAE0CCA480 for ; Wed, 15 Jun 2022 12:47:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347168AbiFOMrx (ORCPT ); Wed, 15 Jun 2022 08:47:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348480AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82558DFF2 for ; Wed, 15 Jun 2022 05:47:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=x60HFrKjnppGazO22bsYW+VPDYInuEcfatYuqW3ZS/Y=; b=NTW9a7sJj1dd4YCYMvQLTmgCDSo1kO4qnCeu5xsA37ROYr3My/4VAgMU3hnblKQjvI/7/hUzgBGQN 3LXQCooZ9cAxmkou7u9AIgClzT4Clzxcb/aE42JoNSsRC6pOSLvevhwY32zQk+DWQD9dJ3YHuYYdaF C0CyRiM9qJCFUtZMfyySSCcErgI1uF5mUeOklQCsP6ENa+GCF5vpF09uX4wj+vNSh2Jf9Z+2kKaPMJ GyUZ1APeHHFL/BJ5NWy7IqqDW7OvfGYJUj5fdEpbsqhs65jRNQDeqFolGvFzlHKKDOqLl9cK/WLtCS JUjhUHgNVieiT+huxIZDAFUqafyqCyg== X-MSG-ID: 533add73-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 04/11] spi: __spi_pump_messages: Consolidate spin_unlocks to goto target Date: Wed, 15 Jun 2022 14:46:27 +0200 Message-Id: <20220615124634.3302867-5-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Signed-off-by: David Jander --- drivers/spi/spi.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index cfff2ff96fa0..fa2d091d2854 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1650,10 +1650,8 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) spin_lock_irqsave(&ctlr->queue_lock, flags); /* Make sure we are not already running a message */ - if (ctlr->cur_msg) { - spin_unlock_irqrestore(&ctlr->queue_lock, flags); + if (ctlr->cur_msg) goto out_unlock; - } /* If another context is idling the device then defer */ if (ctlr->idling) { @@ -1664,10 +1662,8 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) /* Check if the queue is idle */ if (list_empty(&ctlr->queue) || !ctlr->running) { - if (!ctlr->busy) { - spin_unlock_irqrestore(&ctlr->queue_lock, flags); + if (!ctlr->busy) goto out_unlock; - } /* Defer any non-atomic teardown to the thread */ if (!in_kthread) { @@ -1681,7 +1677,6 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); } - spin_unlock_irqrestore(&ctlr->queue_lock, flags); goto out_unlock; } @@ -1703,7 +1698,6 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) spin_lock_irqsave(&ctlr->queue_lock, flags); ctlr->idling = false; ctlr->queue_empty = true; - spin_unlock_irqrestore(&ctlr->queue_lock, flags); goto out_unlock; } @@ -1727,6 +1721,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) return; out_unlock: + spin_unlock_irqrestore(&ctlr->queue_lock, flags); mutex_unlock(&ctlr->io_mutex); } From patchwork Wed Jun 15 12:46:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882285 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4072CCA47E for ; Wed, 15 Jun 2022 12:47:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345740AbiFOMru (ORCPT ); Wed, 15 Jun 2022 08:47:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52908 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234307AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81E39DF4E for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=Rx8m4LW9ySJ0xiERX/MhZmzWCLriIcDzwVdLW/HEd9E=; b=lS8yBClNAU7qTCaBnXDLrUS7sX0w7EST/t0UpwhO7rOmuF7p8QKqzXPWDcW+cbWuGoxidrgDneP7D M3+ENjkhM+1VcpelfSOgDQrxrK6NgrTQB1RGXaiJCgRBqTXY71XwUABsvKPQpLF0e7kwA6iZ+UER/4 rBYxTmiukIAFGcYVbcpxABIdaR7LsOTWOcppnOP+lyKGHUnn9YJdcsXyoNM6W/s8QGpjuFT+ePl5a2 zgitH5cGJWbNOorA86OwbVJcR+4+/bAfRmX98BIaFJuicuZTVTgOhQUXQ+VJs263F7k8zwxEAE5tQC D8ZQQamUZtiqpKc1dcSFmxD2yKOVoEw== X-MSG-ID: 53a3f35d-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 05/11] spi: Remove check for controller idling in spi sync path Date: Wed, 15 Jun 2022 14:46:28 +0200 Message-Id: <20220615124634.3302867-6-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Now that the idling flag is wholly behind the io_mutex, this broken piece of code can be safely removed. Signed-off-by: David Jander --- drivers/spi/spi.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index fa2d091d2854..d8d2b7ac78f2 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3964,10 +3964,6 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s mutex_lock(&ctlr->io_mutex); - /* If another context is idling the device then wait */ - while (ctlr->idling) - usleep_range(10000, 11000); - was_busy = READ_ONCE(ctlr->busy); ret = __spi_pump_transfer_message(ctlr, msg, was_busy); From patchwork Wed Jun 15 12:46:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882282 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA271C433EF for ; Wed, 15 Jun 2022 12:47:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348577AbiFOMrt (ORCPT ); Wed, 15 Jun 2022 08:47:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242442AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp28.bhosted.nl (smtp28.bhosted.nl [IPv6:2a02:9e0:8000::40]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82202DF87 for ; Wed, 15 Jun 2022 05:47:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=h7h2OdTZM5QjhOhXH4N7Lr5PvnITA26Ut5j2+5THjOQ=; b=mR4NmljUUwWqotYmSjTJmP4wo8Tn9wtY4u18bXze+5TQWgcneVWeJfD8O5YKQA8EKN31cHjf/mXWF gPH1waLO4k9q2b22C8rFNG6hHqp3IVBi3uCcY3SQqX7JfehIE4vW45X8Lb6tjAwfqHo4JToZLPTzsT lA/1fZoLCXFlKQx7f61ziJYJKbmM2hageHgxFWeDxj7OvJI/0UxSYW/bc8fCsAdNQtNBI9sedE3FBP b9DkbJ56KG5MZEK4AoXYGr/vMRz/Xka6txN9XTWfVHnBemczx+FCZyQ8+bLX2IGHQR2DMwN7cqD4wG zSeAwndEMepAMae7y+gWZ+Vw7DTWWtw== X-MSG-ID: 53a52f6d-eca9-11ec-8a45-0050569d11ae From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 06/11] spi: Remove check for idling in __spi_pump_messages() Date: Wed, 15 Jun 2022 14:46:29 +0200 Message-Id: <20220615124634.3302867-7-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Since the whole idling transition is locked by the io_mutex now, there is no need to check this flag anymore. Signed-off-by: David Jander --- drivers/spi/spi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d8d2b7ac78f2..71b767a9ad77 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1653,13 +1653,6 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) if (ctlr->cur_msg) goto out_unlock; - /* If another context is idling the device then defer */ - if (ctlr->idling) { - kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); - spin_unlock_irqrestore(&ctlr->queue_lock, flags); - goto out_unlock; - } - /* Check if the queue is idle */ if (list_empty(&ctlr->queue) || !ctlr->running) { if (!ctlr->busy) From patchwork Wed Jun 15 12:46:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89B63CCA473 for ; Wed, 15 Jun 2022 12:47:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348448AbiFOMry (ORCPT ); Wed, 15 Jun 2022 08:47:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52960 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348456AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82657DFF3 for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=SgpqjMAEVJLKSwqAw6RLOsp1PydTE3FJ3MKPVMhSyRY=; b=PaWG1q6o7veSJZn09dKW7JxVRiPta/ZUxWnMIRdO5zbyFjBIho8a6Z+VTCb2UoTXEtoRwp79YGUGO cxPrxQpXdLbpOWh0ctzQvRQukhXr9NkqdEXwvB10pPxUqHVhiV2gS9ll/UFMgWxXFp5blDpMjnlhTA zaF8P6WaZFlgzRqCL5JJSA9S6h7nUqrdaKN1iNJhJZjYyEIX7Uf7r83czFdNVsHfLDnIYpoTJZKEpQ ZUb0D2DYeUf6xltLQqykvmo0GmdD2zw0zp/NMVYHeN+HR2XjTMhUQs643pIOursHq+ESHiuTiQ8y1g +t6uwvAZnG9mVs9hsUrJzyOEY6Qi8tg== X-MSG-ID: 53a6bb85-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 07/11] spi: Remove the now unused ctlr->idling flag Date: Wed, 15 Jun 2022 14:46:30 +0200 Message-Id: <20220615124634.3302867-8-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org The ctlr->idling flag is never checked now, so we don't need to set it either. Signed-off-by: David Jander --- drivers/spi/spi.c | 2 -- include/linux/spi/spi.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 71b767a9ad77..52736e339645 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1674,7 +1674,6 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) } ctlr->busy = false; - ctlr->idling = true; spin_unlock_irqrestore(&ctlr->queue_lock, flags); kfree(ctlr->dummy_rx); @@ -1689,7 +1688,6 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) trace_spi_controller_idle(ctlr); spin_lock_irqsave(&ctlr->queue_lock, flags); - ctlr->idling = false; ctlr->queue_empty = true; goto out_unlock; } diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 74261a83b5fa..c58f46be762f 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -383,7 +383,6 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @pump_messages: work struct for scheduling work to the message pump * @queue_lock: spinlock to syncronise access to message queue * @queue: message queue - * @idling: the device is entering idle state * @cur_msg: the currently in-flight message * @cur_msg_mapped: message has been mapped for DMA * @last_cs: the last chip_select that is recorded by set_cs, -1 on non chip @@ -616,7 +615,6 @@ struct spi_controller { spinlock_t queue_lock; struct list_head queue; struct spi_message *cur_msg; - bool idling; bool busy; bool running; bool rt; From patchwork Wed Jun 15 12:46:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882283 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B866C43334 for ; Wed, 15 Jun 2022 12:47:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242442AbiFOMru (ORCPT ); Wed, 15 Jun 2022 08:47:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345740AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82339DF8A for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=K27EsJYcV5D6XaF1RNfZBWqOwfz0qgxJ/954VGvD+DA=; b=lNzHuEC4QSAign18zu1jKThBnQCz5gsjMWPanK0kKH3yOb96f/UwkJi2nQKQbwsvhX4FP81Tb9PKC R2FrAKwQQ8qLHMOK0XzhGF2UiyxQGdvmKU10lGXwgIAhLRR1V4RlByhIFC3u0sPxlNxd8qZCYWmA85 wOHVXRU13zgf+8sB9zRC/XjZkKEo6IVjqhvw6MOMvWhQlL9/Hkj0tzosEcxN2xmfLOPwdXu9jGSjYS qxfEb5mnBScSjHNSDdNVSl87xVEuouEl9xe1y7gMkfZaFrQDfdBR6JbK1Ijusei6p8Ru/AuM3U6FL9 UjmwvgnudkuATq3uwKd10uFBqeu1rWA== X-MSG-ID: 53a9944d-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH 08/11] spi: Remove unneeded READ_ONCE for ctlr->busy flag Date: Wed, 15 Jun 2022 14:46:31 +0200 Message-Id: <20220615124634.3302867-9-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Now this flag is written entirely in the mutex, so no need for READ_ONCE Signed-off-by: David Jander --- drivers/spi/spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 52736e339645..29f42753ef0f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3955,7 +3955,7 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s mutex_lock(&ctlr->io_mutex); - was_busy = READ_ONCE(ctlr->busy); + was_busy = ctlr->busy; ret = __spi_pump_transfer_message(ctlr, msg, was_busy); if (ret) From patchwork Wed Jun 15 12:46:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882284 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 827DDCCA473 for ; Wed, 15 Jun 2022 12:47:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234307AbiFOMrv (ORCPT ); Wed, 15 Jun 2022 08:47:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347058AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81EA9DF6B for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=F15awN8fVr1aUHPApDU8EiblKTOOr8pm7ISa2F3TCnc=; b=wXYE3EKg+uoyduTjtzVHnRwgw3jmGPUTlaNvjQ8j8rbXCGs9xy51i9rA0HVEcF1GeaHJB81Kjo8gR 6kMhmDIbZn8MHmj0l6Z409MvDWFrnBpQZuaMkk/Q1zaQn0IZeEOcNmXg1WUeJRD1T6/ezoObhnkliy 90exon8i2ieXelutQzoNCxpClptqFM6TcZbOq+N4qAev7PMaQx9L21DKK9wm3PKPWxjH8yAe5nDTgV BJH6RAK4RlYN1vadJ99G2DbtFuTVvOG1OapiXqy6tlxu9vDwPy2h/MVn8yOJfVWQFuJqvicUcOwKyK g9BmH9qrRtSiB/eNTpid18jdKJJC8fQ== X-MSG-ID: 53ad7e96-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 09/11] spi: Set ctlr->cur_msg also in the sync transfer case Date: Wed, 15 Jun 2022 14:46:32 +0200 Message-Id: <20220615124634.3302867-10-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org Some drivers rely on this to point to the currently processed message, so set this here also. Signed-off-by: David Jander --- drivers/spi/spi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 29f42753ef0f..3df84f43918c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3957,6 +3957,7 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s was_busy = ctlr->busy; + ctlr->cur_msg = msg; ret = __spi_pump_transfer_message(ctlr, msg, was_busy); if (ret) goto out; From patchwork Wed Jun 15 12:46:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882289 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4AAC5CCA47E for ; Wed, 15 Jun 2022 12:47:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1347485AbiFOMrx (ORCPT ); Wed, 15 Jun 2022 08:47:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348511AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 826C4E003 for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=sTyj/g7vMjUKwofVqknJ3ZBfE1RGq7JZW5LoUBnzr1g=; b=hmNbLc02/gJa8WmP5S3ebsbBO1TwKpgRHQk4/ZgqbCQuFca18zEhRDuJsD4YJfnRu0EGI4oasQWHN +D5rctkl2msDYsjdDdyIoGQMNS9T5xryDsm721UdAVOeM/+z/Hq95TUbTyBTg/mmA7AZv5eFT/KIyx z//BoDGh5BYcuo1K5/k7DRzeceO7tkhsbDtAIM+WAdVkOgoYN5WSwKX2pSPaSF37BumHawn8OXkmWT i2TJ7n6bwXWr+kdx6OdyAq4OEUtMx8LXl1NnTLhz38Zai+7iETSBL4NB2wZdVTA7cqT25hSUSEsf0Z WEczSuntLWBGhdty+vCkPMmSCdxikIA== X-MSG-ID: 53bf1ed8-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 10/11] spi: Ensure the io_mutex is held until spi_finalize_current_message() Date: Wed, 15 Jun 2022 14:46:33 +0200 Message-Id: <20220615124634.3302867-11-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org This patch introduces a completion that is completed in spi_finalize_current_message() and waited for in __spi_pump_transfer_message(). This way all manipulation of ctlr->cur_msg is done with the io_mutex held and strictly ordered: __spi_pump_transfer_message() will not return until spi_finalize_current_message() is done using ctlr->cur_msg, and its calling context is only touching ctlr->cur_msg after returning. Due to this, we can safely drop the spin-locks around ctlr->cur_msg. Signed-off-by: David Jander --- drivers/spi/spi.c | 32 ++++++++++++++------------------ include/linux/spi/spi.h | 6 ++---- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3df84f43918c..db08cb868652 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1613,11 +1613,14 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr, } } + reinit_completion(&ctlr->cur_msg_completion); ret = ctlr->transfer_one_message(ctlr, msg); if (ret) { dev_err(&ctlr->dev, "failed to transfer one message from queue\n"); return ret; + } else { + wait_for_completion(&ctlr->cur_msg_completion); } return 0; @@ -1704,6 +1707,12 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread) spin_unlock_irqrestore(&ctlr->queue_lock, flags); ret = __spi_pump_transfer_message(ctlr, msg, was_busy); + + if (!ret) + kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); + ctlr->cur_msg = NULL; + ctlr->fallback = false; + mutex_unlock(&ctlr->io_mutex); /* Prod the scheduler in case transfer_one() was busy waiting */ @@ -1897,12 +1906,9 @@ void spi_finalize_current_message(struct spi_controller *ctlr) { struct spi_transfer *xfer; struct spi_message *mesg; - unsigned long flags; int ret; - spin_lock_irqsave(&ctlr->queue_lock, flags); mesg = ctlr->cur_msg; - spin_unlock_irqrestore(&ctlr->queue_lock, flags); if (!ctlr->ptp_sts_supported && !ctlr->transfer_one) { list_for_each_entry(xfer, &mesg->transfers, transfer_list) { @@ -1936,20 +1942,7 @@ void spi_finalize_current_message(struct spi_controller *ctlr) mesg->prepared = false; - if (!mesg->sync) { - /* - * This message was sent via the async message queue. Handle - * the queue and kick the worker thread to do the - * idling/shutdown or send the next message if needed. - */ - spin_lock_irqsave(&ctlr->queue_lock, flags); - WARN(ctlr->cur_msg != mesg, - "Finalizing queued message that is not the current head of queue!"); - ctlr->cur_msg = NULL; - ctlr->fallback = false; - kthread_queue_work(ctlr->kworker, &ctlr->pump_messages); - spin_unlock_irqrestore(&ctlr->queue_lock, flags); - } + complete(&ctlr->cur_msg_completion); trace_spi_message_done(mesg); @@ -3036,6 +3029,7 @@ int spi_register_controller(struct spi_controller *ctlr) } ctlr->bus_lock_flag = 0; init_completion(&ctlr->xfer_completion); + init_completion(&ctlr->cur_msg_completion); if (!ctlr->max_dma_len) ctlr->max_dma_len = INT_MAX; @@ -3962,6 +3956,9 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s if (ret) goto out; + ctlr->cur_msg = NULL; + ctlr->fallback = false; + if (!was_busy) { kfree(ctlr->dummy_rx); ctlr->dummy_rx = NULL; @@ -4013,7 +4010,6 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message) * will catch those cases. */ if (READ_ONCE(ctlr->queue_empty)) { - message->sync = true; message->actual_length = 0; message->status = -EINPROGRESS; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index c58f46be762f..c56e0d240a58 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -384,6 +384,7 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @queue_lock: spinlock to syncronise access to message queue * @queue: message queue * @cur_msg: the currently in-flight message + * @cur_msg_completion: a completion for the current in-flight message * @cur_msg_mapped: message has been mapped for DMA * @last_cs: the last chip_select that is recorded by set_cs, -1 on non chip * selected @@ -615,6 +616,7 @@ struct spi_controller { spinlock_t queue_lock; struct list_head queue; struct spi_message *cur_msg; + struct completion cur_msg_completion; bool busy; bool running; bool rt; @@ -989,7 +991,6 @@ struct spi_transfer { * @state: for use by whichever driver currently owns the message * @resources: for resource management when the spi message is processed * @prepared: spi_prepare_message was called for the this message - * @sync: this message took the direct sync path skipping the async queue * * A @spi_message is used to execute an atomic sequence of data transfers, * each represented by a struct spi_transfer. The sequence is "atomic" @@ -1042,9 +1043,6 @@ struct spi_message { /* spi_prepare_message was called for this message */ bool prepared; - - /* this message is skipping the async queue */ - bool sync; }; static inline void spi_message_init_no_memset(struct spi_message *m) From patchwork Wed Jun 15 12:46:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Jander X-Patchwork-Id: 12882293 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8E8FCCA481 for ; Wed, 15 Jun 2022 12:47:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348511AbiFOMrz (ORCPT ); Wed, 15 Jun 2022 08:47:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348537AbiFOMrs (ORCPT ); Wed, 15 Jun 2022 08:47:48 -0400 Received: from smtp16.bhosted.nl (smtp16.bhosted.nl [IPv6:2a02:9e0:8000::27]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 829A1E01C for ; Wed, 15 Jun 2022 05:47:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonic.nl; s=202111; h=content-transfer-encoding:mime-version:references:in-reply-to:message-id:date: subject:cc:to:from:from; bh=jg6S3PjeI5qTEyeBZrsTnAtoxgxaUwKcgRhBM8dhK4U=; b=rHTeOE4tzt7ZLcoRW1pRINDmnDeVvcgsgC0c7jYVjEfw55H9fGrmr1ZZDQag4GWIa3dd32PhnTEoy 5l5D1uvwp/9W3Zp/lReZOWruG+7UBgk0yBBLN3HcgrJEhrkpwR3F/C2t3Wf2C0bia0U515jyHOvBy+ IKwHqzJMx69zCPXpYRTbo6RSDmZBnAxOnbKWftErPpQSGihTkDaRgq8eB8nr0SJqiWCmInp5StUrXC YmgKrm+ahbWO9qBDCLmawvFls69qU3VP+HnyZusms/B0lLB4Uks8ZPxl2kHVAWRElDMBjW/02qAKUa bI5as1XXqVWUJ9Ee4J9ft7d3nK5fPpA== X-MSG-ID: 53d59342-eca9-11ec-9051-0050569d2c73 From: David Jander To: Mark Brown Cc: linux-spi@vger.kernel.org, Marc Kleine-Budde , Andrew Lunn , David Jander Subject: [RFC] [PATCH v2 11/11] spi: opportunistically skip ctlr->cur_msg_completion Date: Wed, 15 Jun 2022 14:46:34 +0200 Message-Id: <20220615124634.3302867-12-david@protonic.nl> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20220615124634.3302867-1-david@protonic.nl> References: <20220615124634.3302867-1-david@protonic.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org There are only a few drivers that do not call spi_finalize_current_message() in the context of transfer_one_message(), and even for those cases the completion ctlr->cur_msg_completion is not needed always. The calls to complete() and wait_for_completion() each take a spin-lock, which is costly. This patch makes it possible to avoid those calls in the big majority of cases, by introducing two flags that with the help of ordering via barriers can avoid using the completion safely. In case of a race with the context calling spi_finalize_current_message(), the scheme errs on the safe side and takes the completion. The impact of this patch is worth the effort: On a i.MX8MM SoC, the time the SPI bus is idle between two consecutive calls to spi_sync(), is reduced from 19.6us to 16.8us... roughly 15%. Signed-off-by: David Jander --- drivers/spi/spi.c | 27 +++++++++++++++++++++++++-- include/linux/spi/spi.h | 8 ++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index db08cb868652..ef37f043fd17 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1613,14 +1613,34 @@ static int __spi_pump_transfer_message(struct spi_controller *ctlr, } } + /* + * Drivers implementation of transfer_one_message() must arrange for + * spi_finalize_current_message() to get called. Most drivers will do + * this in the calling context, but some don't. For those cases, a + * completion is used to guarantee that this function does not return + * until spi_finalize_current_message() is done accessing + * ctlr->cur_msg. + * Use of the following two flags enable to opportunistically skip the + * use of the completion since its use involves expensive spin locks. + * In case of a race with the context that calls + * spi_finalize_current_message() the completion will always be used, + * due to strict ordering of these flags using barriers. + */ + WRITE_ONCE(ctlr->cur_msg_incomplete, true); + WRITE_ONCE(ctlr->cur_msg_need_completion, false); reinit_completion(&ctlr->cur_msg_completion); + smp_wmb(); /* make these available to spi_finalize_current_message */ + ret = ctlr->transfer_one_message(ctlr, msg); if (ret) { dev_err(&ctlr->dev, "failed to transfer one message from queue\n"); return ret; } else { - wait_for_completion(&ctlr->cur_msg_completion); + WRITE_ONCE(ctlr->cur_msg_need_completion, true); + smp_mb(); /* see spi_finalize_current_message()... */ + if (READ_ONCE(ctlr->cur_msg_incomplete)) + wait_for_completion(&ctlr->cur_msg_completion); } return 0; @@ -1942,7 +1962,10 @@ void spi_finalize_current_message(struct spi_controller *ctlr) mesg->prepared = false; - complete(&ctlr->cur_msg_completion); + WRITE_ONCE(ctlr->cur_msg_incomplete, false); + smp_mb(); /* See __spi_pump_transfer_message()... */ + if (READ_ONCE(ctlr->cur_msg_need_completion)) + complete(&ctlr->cur_msg_completion); trace_spi_message_done(mesg); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index c56e0d240a58..eb0d316e3c36 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -385,6 +385,12 @@ extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 ch * @queue: message queue * @cur_msg: the currently in-flight message * @cur_msg_completion: a completion for the current in-flight message + * @cur_msg_incomplete: Flag used internally to opportunistically skip + * the @cur_msg_completion. This flag is used to check if the driver has + * already called spi_finalize_current_message(). + * @cur_msg_need_completion: Flag used internally to opportunistically skip + * the @cur_msg_completion. This flag is used to signal the context that + * is running spi_finalize_current_message() that it needs to complete() * @cur_msg_mapped: message has been mapped for DMA * @last_cs: the last chip_select that is recorded by set_cs, -1 on non chip * selected @@ -617,6 +623,8 @@ struct spi_controller { struct list_head queue; struct spi_message *cur_msg; struct completion cur_msg_completion; + bool cur_msg_incomplete; + bool cur_msg_need_completion; bool busy; bool running; bool rt;