From patchwork Fri Nov 30 14:55:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sperl X-Patchwork-Id: 10706471 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CCEB513B0 for ; Fri, 30 Nov 2018 14:56:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BC8A7283B1 for ; Fri, 30 Nov 2018 14:56:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B0AEA2BC2D; Fri, 30 Nov 2018 14:56:09 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E3E70283B1 for ; Fri, 30 Nov 2018 14:56:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726558AbeLACFm (ORCPT ); Fri, 30 Nov 2018 21:05:42 -0500 Received: from 212-186-180-163.static.upcbusiness.at ([212.186.180.163]:59440 "EHLO cgate.sperl.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726519AbeLACFm (ORCPT ); Fri, 30 Nov 2018 21:05:42 -0500 Received: from hc1.intern.sperl.org (account martin@sperl.org [10.10.10.59] verified) by sperl.org (CommuniGate Pro SMTP 6.2.1 _community_) with ESMTPSA id 7752009; Fri, 30 Nov 2018 14:56:05 +0000 From: kernel@martin.sperl.org To: Mark Brown , linux-spi@vger.kernel.org Cc: Martin Sperl Subject: [PATCH V1] spi: core: wake kworker only when there is a message in the queue Date: Fri, 30 Nov 2018 14:55:49 +0000 Message-Id: <20181130145549.5265-1-kernel@martin.sperl.org> X-Mailer: git-send-email 2.11.0 Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Martin Sperl Right now the worker thread running spi_pump_message is always woken during spi_finalize_current_message. When spi_sync is running alone with no other spi devices connected to the bus the worker thread is woken during spi_finalize_current_message. This is totally unnecessary in the case that there is no message queued. This is less of a problem when the worker kthread is used to control the spi bus, but even there it is unnecessary and wasting CPU cycles. So we only enable the worker thread when the queue is not empty. For spi_sync transfers in a tight loop (say 40k messages/s) this avoids the penalty of waking the worker thread 40k times/s. On a rasperry pi 3 with 4 cores the results in 32% of a single core only to find out that there is nothing in the queue and it can go back to sleep. With this patch applied the spi-worker is not even woken one! I believe I have also seen situations where during a spi_sync loop the worker thread (triggered by the last message finished) is slightly faster and _wins_ the race to process the message, so we are actually running the kthread and letting it do some work... This is also no longer observed with this patch applied as. Signed-off-by: Martin Sperl --- More details: The "running in threaded mode" while it is supposed to run immediately can be seen by these temporarily exposed extra counters: ==> /sys/class/spi_master/spi0/statistics/pump_message <== 16250 ==> /sys/class/spi_master/spi0/statistics/pump_message_already_running <== 8093 ==> /sys/class/spi_master/spi0/statistics/pump_message_idling <== 0 ==> /sys/class/spi_master/spi0/statistics/pump_message_in_kthread <== 8121 So out of 16250 times that pump_message is called 8121 times the call was in kthread and 8093 times the message pump was already running. That means that a few times the kthread must have won the race and the non-kthread version lost or might even have waited in spin_lock_irqsave. Signed-off-by: Martin Sperl --- drivers/spi/spi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 6ca59406b0b7..0f473d1b01f9 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1416,7 +1416,9 @@ void spi_finalize_current_message(struct spi_controller *ctlr) spin_lock_irqsave(&ctlr->queue_lock, flags); ctlr->cur_msg = NULL; ctlr->cur_msg_prepared = false; - kthread_queue_work(&ctlr->kworker, &ctlr->pump_messages); + /* only wake message_pump if there is anything in the queue */ + if (!list_empty(&ctlr->queue)) + kthread_queue_work(&ctlr->kworker, &ctlr->pump_messages); spin_unlock_irqrestore(&ctlr->queue_lock, flags); trace_spi_message_done(mesg);