Received: by 2002:a05:6358:16cd:b0:dc:6189:e246 with SMTP id r13csp618585rwl; Fri, 4 Nov 2022 04:32:25 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4fqZxWfH/5gXfb+IU25MdqyxSISsAFmEgBnktYLGs14nx9qcZGIP9hn54Q7f5Jjmg9+8NN X-Received: by 2002:a17:907:2cf1:b0:7ad:f558:e148 with SMTP id hz17-20020a1709072cf100b007adf558e148mr17709376ejc.274.1667561544999; Fri, 04 Nov 2022 04:32:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1667561544; cv=none; d=google.com; s=arc-20160816; b=wNflf1y1Hzg1tS7DTFFiDw4fohgBx0qhbWBtymnHZm/1WjJv0SIZ62lyLbwbezUPzv HabO8OeqNvRCWf6yZ9+6ye47YeYUrTPw9f7e94fnXm+yDjEMpRYDCjNZlC1le0L48CZr qoooZDc25LF5CMYRc6lTKOBLX2pN0bPbAA3XpvnZiY0l0t6Wfa8Sz60XzCi+JhfqUcaY QgAlhghs6wB5LFhc1fbFMBWmhlSxFPkmwdgMu7V5RtCaLJW5NL0QetDj0skMoFCIJ9tP wRWDGkJp6TanAchdWyl3DzyOm8q6g800joimJxz5tFgRFxw/IbS0wiMscAQHHE9AtW98 VFDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:subject:cc:to:from :date:references:in-reply-to:message-id:mime-version:user-agent :feedback-id:dkim-signature; bh=D6oyZ5y/hTno75t/vlOsR6wzOKZJld9FzlGSxrexK0E=; b=XV7c69kTZg3pFl6BDKx74BQei+FFnZbSGCgXLucuC8FmfyRR1YfgP34Z4OrB1UBV5R tY7ncbm7eNqVqgd4+LtqwGcDFDBf5BTyqemvlP56DDA1OFnGqmx6VUVIJpc6FOG1vxho jADLGOI7zEPofRxTFxfD25XBAMboXEdEsKnJoCpK4/vc7qQkocy7NVVUholSKHu+cTh7 bhIlDXz9uqm+qX3MVms0+UVbAIEVBYY49Gmya7ZQ2SCex3if0kmpIvdDpj7d4QKamNNd QguArud9EqIzpjNz1AYSQjrhQxCXlcqCxZhFXnNl4zgccIK3VytrDKqzE8VUKCAybnxZ ebnA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TBGLLB0M; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n10-20020a05640205ca00b0045c2e7e5532si5908162edx.585.2022.11.04.04.32.01; Fri, 04 Nov 2022 04:32:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=TBGLLB0M; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231817AbiKDKvP (ORCPT + 96 others); Fri, 4 Nov 2022 06:51:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231807AbiKDKvK (ORCPT ); Fri, 4 Nov 2022 06:51:10 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A78B2BB13 for ; Fri, 4 Nov 2022 03:51:08 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id E708362150 for ; Fri, 4 Nov 2022 10:51:07 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D7539C433D7; Fri, 4 Nov 2022 10:51:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1667559067; bh=4Bt3wT7yXYgAiC80JzTz8HYvGVPTyhH/6jt4qkLU5C4=; h=In-Reply-To:References:Date:From:To:Cc:Subject:From; b=TBGLLB0Mkp6lWt4L6AVAi9kYEdV6CeTFgjzRq2iTVXD7dhW26SK7IXRBhgk5rQj6R zbyHjw41OsJKZcfzvEbvefYl4UK0K1Gu9bqTBGCsel5TK9g1O4rmd3kw9BSd5bgOzW nOHffAzUTGF6x7kiCgfMsrH2SaB02Rf48BPLprmaYSOMOCESzFrravtxJAqEJT/t35 K9p7cifssD/I14P84MDJzHqypnfevL1+nvKZNlGwIDfBLyJujziCkHUvfwtKoI4yX8 hDVElXeLnK45I90wCtBf+oLvVCocgteXbtw1NKXVvp/hkfCDROsTiqRALESiDR+8qP E3QSHeXSsPP8A== Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailauth.nyi.internal (Postfix) with ESMTP id 800A927C0054; Fri, 4 Nov 2022 06:51:05 -0400 (EDT) Received: from imap51 ([10.202.2.101]) by compute3.internal (MEProxy); Fri, 04 Nov 2022 06:51:05 -0400 X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrvddugddulecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefofgggkfgjfhffhffvvefutgfgsehtqhertderreejnecuhfhrohhmpedftehr nhguuceuvghrghhmrghnnhdfuceorghrnhgusehkvghrnhgvlhdrohhrgheqnecuggftrf grthhtvghrnhepgeelhfelvdelheehteffjeehkeduvdeggeekieefleeuteeluddufeek gedtuefhnecuffhomhgrihhnpehlfihnrdhnvghtnecuvehluhhsthgvrhfuihiivgeptd enucfrrghrrghmpehmrghilhhfrhhomheprghrnhguodhmvghsmhhtphgruhhthhhpvghr shhonhgrlhhithihqdduvdekhedujedtvdegqddvkeejtddtvdeigedqrghrnhgupeepkh gvrhhnvghlrdhorhhgsegrrhhnuggsrdguvg X-ME-Proxy: Feedback-ID: i36794607:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id DB4F5B603ED; Fri, 4 Nov 2022 06:51:04 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.7.0-alpha0-1087-g968661d8e1-fm-20221021.001-g968661d8 Mime-Version: 1.0 Message-Id: In-Reply-To: <8bd1dc3b-e1f0-e7f9-bf65-8d243c65adb5@opensynergy.com> References: <20220825134449.18803-1-harald.mommer@opensynergy.com> <8bd1dc3b-e1f0-e7f9-bf65-8d243c65adb5@opensynergy.com> Date: Fri, 04 Nov 2022 11:50:45 +0100 From: "Arnd Bergmann" To: "Harald Mommer" , "Harald Mommer" Cc: virtio-dev@lists.oasis-open.org, linux-can@vger.kernel.org, Netdev , linux-kernel@vger.kernel.org, "Wolfgang Grandegger" , "Marc Kleine-Budde" , "David S . Miller" , "Eric Dumazet" , "Jakub Kicinski" , "Paolo Abeni" , "Dariusz Stojaczyk" , "Stratos Mailing List" Subject: Re: [virtio-dev] [RFC PATCH 1/1] can: virtio: Initial virtio CAN driver. Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Nov 3, 2022, at 13:26, Harald Mommer wrote: > On 25.08.22 20:21, Arnd Bergmann wrote: >> ... > The messages are not necessarily processed in sequence by the CAN stac= k.=20 > CAN is priority based. The lower the CAN ID the higher the priority. S= o=20 > a message with CAN ID 0x100 can surpass a message with ID 0x123 if the=20 > hardware is not just simple basic CAN controller using a single TX=20 > mailbox with a FIFO queue on top of it. > > Thinking about this the code becomes more complex with the array. What= I=20 > get from the device when the message has been processed is a pointer t= o=20 > the processed message by virtqueue_get_buf(). I can then simply do a=20 > list_del(), free the message and done. Ok >>> +#ifdef DEBUG >>> +static void __attribute__((unused)) >>> +virtio_can_hexdump(const void *data, size_t length, size_t base) >>> +{ >>> +#define VIRTIO_CAN_MAX_BYTES_PER_LINE 16u >> This seems to duplicate print_hex_dump(), maybe just use that? > Checked where it's still used. The code is not disabled by #ifdef DEBU= G=20 > but simply commented out. Under this circumstances it's for now best t= o=20 > simply remove the code now and also the commented out places where is=20 > was used at some time in the past. Even better. >>> + >>> + while (!virtqueue_get_buf(vq, &len) && !virtqueue_is_broken(= vq)) >>> + cpu_relax(); >>> + >>> + mutex_unlock(&priv->ctrl_lock); >> A busy loop is probably not what you want here. Maybe just >> wait_for_completion() until the callback happens? > > Was done in the same way as elsewhere=20 > (virtio_console.c/__send_control_msg() &=20 > virtio_net.c/virtnet_send_command()). Yes, wait_for_completion() is=20 > better, this avoids polling. Ok. FWIW, The others seem to do it like this because they are in non-atomic context where it is not allowed to call wait_for_completion(), but since you already have the mutex here, you know that sleeping is permitted.=20 >>> + /* Push loopback echo. Will be looped back on TX interrupt/T= X NAPI */ >>> + can_put_echo_skb(skb, dev, can_tx_msg->putidx, 0); >>> + >>> + err =3D virtqueue_add_sgs(vq, sgs, 1u, 1u, can_tx_msg, GFP_A= TOMIC); >>> + if (err !=3D 0) { >>> + list_del(&can_tx_msg->list); >>> + virtio_can_free_tx_idx(priv, can_tx_msg->prio, >>> + can_tx_msg->putidx); >>> + netif_stop_queue(dev); >>> + spin_unlock_irqrestore(&priv->tx_lock, flags); >>> + kfree(can_tx_msg); >>> + if (err =3D=3D -ENOSPC) >>> + netdev_info(dev, "TX: Stop queue, no space l= eft\n"); >>> + else >>> + netdev_warn(dev, "TX: Stop queue, reason =3D= %d\n", err); >>> + return NETDEV_TX_BUSY; >>> + } >>> + >>> + if (!virtqueue_kick(vq)) >>> + netdev_err(dev, "%s(): Kick failed\n", __func__); >>> + >>> + spin_unlock_irqrestore(&priv->tx_lock, flags); >> There should not be a need for a spinlock or disabling interrupts >> in the xmit function. What exactly are you protecting against here? > > I'm using 2 NAPIs, one for TX and one for RX. The RX NAPI just receive= s=20 > RX messages and is of no interest here. The TX NAPI handles the TX=20 > messages which have been processed by the virtio CAN device in=20 > virtio_can_read_tx_queue(). If this was done without the TX NAPI this=20 > would have been done by the TX interrupt directly, no difference. > > In virtio_can_start_xmit() > > * Reserve putidx - done by an own mechanism using list operations in=20 > tx_putidx_list > > Could be that it's simpler to use idr_alloc() and friends getting thos= e=20 > numbers to get rid of this own mechanism, not sure yet. But this needs= a=20 > locks as it's based on a linked list and the list operation has to be=20 > protected. Right, makes sense. Lockless transmission should generally work if your transmission queue is a strictly ordered ring buffer where you just need to atomically update the index, but you are right that this doesn't work with a linked list. This probably directly ties into the specification of your tx virtqueue: if the device could guarantee that any descriptors are processed in sequence, you could avoid the spinlock in the tx path for a small performance optimization, but then you have to decide on the sequence in the driver already, which impacts the latency for high-priority frames that get queued to the device. It's possible that the reordering in the device would not be as critical if you correctly implement the byte queue limits. >>> + kfree(can_tx_msg); >>> + >>> + /* Flow control */ >>> + if (netif_queue_stopped(dev)) { >>> + netdev_info(dev, "TX ACK: Wake up stopped queue\n"); >>> + netif_wake_queue(dev); >>> + } >> You may want to add netdev_sent_queue()/netdev_completed_queue() >> based BQL flow control here as well, so you don't have to rely on the >> queue filling up completely. > Not addressed, not yet completely understood. https://lwn.net/Articles/454390/ is an older article but should still explain the background. Without byte queue limits, you risk introducing unbounded TX latency on a congested interface. Ideally, the host device implementation should only send back the 'completed' interrupt after a frame has left the physical hardware. In this case, BQL will manage both the TX queue in the guest driver and the queue in the host device to keep the total queue length short enough to guarantee low latency even for low-priority frames but long enough to maintain wire-speed throughput. >>> + >>> + register_virtio_can_dev(dev); >>> + >>> + /* Initialize virtqueues */ >>> + err =3D virtio_can_find_vqs(priv); >>> + if (err !=3D 0) >>> + goto on_failure; >> Should the register_virtio_can_dev() be done here? I would expect thi= s to be >> the last thing after setting up the queues. > > Doing so makes the code somewhat simpler and shorter =3D better. The problem is that as soon as an interface is registered, you can have userspace sending data to it. This may be a short race, but I fear that this would cause data corruption if data gets queued before the device is fully operational. >>> +#ifdef CONFIG_PM_SLEEP >>> + .freeze =3D virtio_can_freeze, >>> + .restore =3D virtio_can_restore, >>> +#endif >> You can remove the #ifdef here and above, and replace that with the >> pm_sleep_ptr() macro in the assignment. > > This pm_sleep_ptr(_ptr) macro returns either the argument when=20 > CONFIG_PM_SLEEP is defined or NULL. But in struct virtio_driver there = is > > #ifdef CONFIG_PM =C2=A0 int(*freeze) ...; =C2=A0 int(*restore) ...; #e= ndif > > so without CONFIG_PM there are no freeze and restore structure members. > > So > > =C2=A0 .freeze =3D pm_sleep_ptr(virtio_can_freeze) > > won't work. I think this is a mistake in the virtio_driver definition, it would be best to send a small patch that removes this #ifdef along with your driver. Arnd