From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF5A01F9F79; Tue, 17 Dec 2024 17:30:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734456649; cv=none; b=Mkt6tuVdrIdprrI0czpu7cidVa2N9ZiwF24GNDSxgkiI2Xn7gIxKbnwvlzXNIYV/LsY/bL1B+CV3EVd98KWOZWjTlOdDBcCDWKcRmCTSovcyZBZz/h+p7iF//nNkGmFH3ru3mVkLec5r+wnlWJlVbn2buJYh8dm8iQ69Kl1hARk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1734456649; c=relaxed/simple; bh=HmqSiW5z1WEwZkpn+cNl5o+PAHtBaMZDsfGeD72+0zA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PmKKbycJWcgVbjTtqAYJj4yROXl+vowZy1KE46Xe63wAU5xZfDrisRtaJXN2L4B5kNhI1O77qn7S7P6rgUb9i068Tw/A5aHubmhEIBmxPUcsHqFMbEauvH8zam30vDukdSWujPgJxNqpCxZOwhC5YhRB1OQxeS3slhg5SGjlyno= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=SpFOGll1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="SpFOGll1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 533D3C4CED3; Tue, 17 Dec 2024 17:30:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1734456648; bh=HmqSiW5z1WEwZkpn+cNl5o+PAHtBaMZDsfGeD72+0zA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SpFOGll102DDUS/RL81gbF/EhCT+K55qbGeFsOvpSp4DTjsSO/zPpP7O6dVvjvb9S uz/lnTvpn0Kvuin4s7nJgC6kivBL1LwwXO5UT1LFIu8B7Rt8+0UJi8IQCW3isc0R0m mqwmm/NfZtPcrlw953A5ruR3fa4zh4erBDy8vTQQ= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Nikita Yushchenko , Yoshihiro Shimoda , Jakub Kicinski , Sasha Levin Subject: [PATCH 6.12 124/172] net: renesas: rswitch: fix race window between tx start and complete Date: Tue, 17 Dec 2024 18:08:00 +0100 Message-ID: <20241217170551.485239451@linuxfoundation.org> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20241217170546.209657098@linuxfoundation.org> References: <20241217170546.209657098@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Nikita Yushchenko [ Upstream commit 0c9547e6ccf40455b0574cf589be3b152a3edf5b ] If hardware is already transmitting, it can start handling the descriptor being written to immediately after it observes updated DT field, before the queue is kicked by a write to GWTRC. If the start_xmit() execution is preempted at unfortunate moment, this transmission can complete, and interrupt handled, before gq->cur gets updated. With the current implementation of completion, this will cause the last entry not completed. Fix that by changing completion loop to check DT values directly, instead of depending on gq->cur. Fixes: 3590918b5d07 ("net: ethernet: renesas: Add support for "Ethernet Switch"") Signed-off-by: Nikita Yushchenko Reviewed-by: Yoshihiro Shimoda Link: https://patch.msgid.link/20241208095004.69468-3-nikita.yoush@cogentembedded.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/renesas/rswitch.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/renesas/rswitch.c b/drivers/net/ethernet/renesas/rswitch.c index 32b32aa7e01f..c251becef6f8 100644 --- a/drivers/net/ethernet/renesas/rswitch.c +++ b/drivers/net/ethernet/renesas/rswitch.c @@ -862,13 +862,10 @@ static void rswitch_tx_free(struct net_device *ndev) struct rswitch_ext_desc *desc; struct sk_buff *skb; - for (; rswitch_get_num_cur_queues(gq) > 0; - gq->dirty = rswitch_next_queue_index(gq, false, 1)) { - desc = &gq->tx_ring[gq->dirty]; - if ((desc->desc.die_dt & DT_MASK) != DT_FEMPTY) - break; - + desc = &gq->tx_ring[gq->dirty]; + while ((desc->desc.die_dt & DT_MASK) == DT_FEMPTY) { dma_rmb(); + skb = gq->skbs[gq->dirty]; if (skb) { rdev->ndev->stats.tx_packets++; @@ -879,7 +876,10 @@ static void rswitch_tx_free(struct net_device *ndev) dev_kfree_skb_any(gq->skbs[gq->dirty]); gq->skbs[gq->dirty] = NULL; } + desc->desc.die_dt = DT_EEMPTY; + gq->dirty = rswitch_next_queue_index(gq, false, 1); + desc = &gq->tx_ring[gq->dirty]; } } @@ -1685,6 +1685,8 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = skb; gq->unmap_addrs[(gq->cur + nr_desc - 1) % gq->ring_size] = dma_addr_orig; + dma_wmb(); + /* DT_FSTART should be set at last. So, this is reverse order. */ for (i = nr_desc; i-- > 0; ) { desc = &gq->tx_ring[rswitch_next_queue_index(gq, true, i)]; @@ -1695,8 +1697,6 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd goto err_unmap; } - wmb(); /* gq->cur must be incremented after die_dt was set */ - gq->cur = rswitch_next_queue_index(gq, true, nr_desc); rswitch_modify(rdev->addr, GWTRC(gq->index), 0, BIT(gq->index % 32)); -- 2.39.5