Skip to content

Commit 78034cb

Browse files
lsun100jwrdegoede
authored andcommitted
platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors
This commit fixes tmfifo console stuck issue when the virtual networking interface is in down state. In such case, the network Rx descriptors runs out and causes the Rx network packet staying in the head of the tmfifo thus blocking the console packets. The fix is to drop the Rx network packet when no more Rx descriptors. Function name mlxbf_tmfifo_release_pending_pkt() is also renamed to mlxbf_tmfifo_release_pkt() to be more approperiate. Fixes: 1357dfd ("platform/mellanox: Add TmFifo driver for Mellanox BlueField Soc") Signed-off-by: Liming Sun <[email protected]> Reviewed-by: Vadim Pasternak <[email protected]> Reviewed-by: David Thompson <[email protected]> Link: https://lore.kernel.org/r/8c0177dc938ae03f52ff7e0b62dbeee74b7bec09.1693322547.git.limings@nvidia.com Signed-off-by: Hans de Goede <[email protected]>
1 parent 0bb80ec commit 78034cb

File tree

1 file changed

+49
-17
lines changed

1 file changed

+49
-17
lines changed

drivers/platform/mellanox/mlxbf-tmfifo.c

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ struct mlxbf_tmfifo;
5959
* @vq: pointer to the virtio virtqueue
6060
* @desc: current descriptor of the pending packet
6161
* @desc_head: head descriptor of the pending packet
62+
* @drop_desc: dummy desc for packet dropping
6263
* @cur_len: processed length of the current descriptor
6364
* @rem_len: remaining length of the pending packet
6465
* @pkt_len: total length of the pending packet
@@ -75,6 +76,7 @@ struct mlxbf_tmfifo_vring {
7576
struct virtqueue *vq;
7677
struct vring_desc *desc;
7778
struct vring_desc *desc_head;
79+
struct vring_desc drop_desc;
7880
int cur_len;
7981
int rem_len;
8082
u32 pkt_len;
@@ -86,6 +88,14 @@ struct mlxbf_tmfifo_vring {
8688
struct mlxbf_tmfifo *fifo;
8789
};
8890

91+
/* Check whether vring is in drop mode. */
92+
#define IS_VRING_DROP(_r) ({ \
93+
typeof(_r) (r) = (_r); \
94+
(r->desc_head == &r->drop_desc ? true : false); })
95+
96+
/* A stub length to drop maximum length packet. */
97+
#define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0)
98+
8999
/* Interrupt types. */
90100
enum {
91101
MLXBF_TM_RX_LWM_IRQ,
@@ -262,6 +272,7 @@ static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo,
262272
vring->align = SMP_CACHE_BYTES;
263273
vring->index = i;
264274
vring->vdev_id = tm_vdev->vdev.id.device;
275+
vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN;
265276
dev = &tm_vdev->vdev.dev;
266277

267278
size = vring_size(vring->num, vring->align);
@@ -367,7 +378,7 @@ static u32 mlxbf_tmfifo_get_pkt_len(struct mlxbf_tmfifo_vring *vring,
367378
return len;
368379
}
369380

370-
static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring)
381+
static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring)
371382
{
372383
struct vring_desc *desc_head;
373384
u32 len = 0;
@@ -596,19 +607,25 @@ static void mlxbf_tmfifo_rxtx_word(struct mlxbf_tmfifo_vring *vring,
596607

597608
if (vring->cur_len + sizeof(u64) <= len) {
598609
/* The whole word. */
599-
if (is_rx)
600-
memcpy(addr + vring->cur_len, &data, sizeof(u64));
601-
else
602-
memcpy(&data, addr + vring->cur_len, sizeof(u64));
610+
if (!IS_VRING_DROP(vring)) {
611+
if (is_rx)
612+
memcpy(addr + vring->cur_len, &data,
613+
sizeof(u64));
614+
else
615+
memcpy(&data, addr + vring->cur_len,
616+
sizeof(u64));
617+
}
603618
vring->cur_len += sizeof(u64);
604619
} else {
605620
/* Leftover bytes. */
606-
if (is_rx)
607-
memcpy(addr + vring->cur_len, &data,
608-
len - vring->cur_len);
609-
else
610-
memcpy(&data, addr + vring->cur_len,
611-
len - vring->cur_len);
621+
if (!IS_VRING_DROP(vring)) {
622+
if (is_rx)
623+
memcpy(addr + vring->cur_len, &data,
624+
len - vring->cur_len);
625+
else
626+
memcpy(&data, addr + vring->cur_len,
627+
len - vring->cur_len);
628+
}
612629
vring->cur_len = len;
613630
}
614631

@@ -709,8 +726,16 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
709726
/* Get the descriptor of the next packet. */
710727
if (!vring->desc) {
711728
desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx);
712-
if (!desc)
713-
return false;
729+
if (!desc) {
730+
/* Drop next Rx packet to avoid stuck. */
731+
if (is_rx) {
732+
desc = &vring->drop_desc;
733+
vring->desc_head = desc;
734+
vring->desc = desc;
735+
} else {
736+
return false;
737+
}
738+
}
714739
} else {
715740
desc = vring->desc;
716741
}
@@ -743,17 +768,24 @@ static bool mlxbf_tmfifo_rxtx_one_desc(struct mlxbf_tmfifo_vring *vring,
743768
vring->rem_len -= len;
744769

745770
/* Get the next desc on the chain. */
746-
if (vring->rem_len > 0 &&
771+
if (!IS_VRING_DROP(vring) && vring->rem_len > 0 &&
747772
(virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) {
748773
idx = virtio16_to_cpu(vdev, desc->next);
749774
desc = &vr->desc[idx];
750775
goto mlxbf_tmfifo_desc_done;
751776
}
752777

753-
/* Done and release the pending packet. */
754-
mlxbf_tmfifo_release_pending_pkt(vring);
778+
/* Done and release the packet. */
755779
desc = NULL;
756780
fifo->vring[is_rx] = NULL;
781+
if (!IS_VRING_DROP(vring)) {
782+
mlxbf_tmfifo_release_pkt(vring);
783+
} else {
784+
vring->pkt_len = 0;
785+
vring->desc_head = NULL;
786+
vring->desc = NULL;
787+
return false;
788+
}
757789

758790
/*
759791
* Make sure the load/store are in order before
@@ -933,7 +965,7 @@ static void mlxbf_tmfifo_virtio_del_vqs(struct virtio_device *vdev)
933965

934966
/* Release the pending packet. */
935967
if (vring->desc)
936-
mlxbf_tmfifo_release_pending_pkt(vring);
968+
mlxbf_tmfifo_release_pkt(vring);
937969
vq = vring->vq;
938970
if (vq) {
939971
vring->vq = NULL;

0 commit comments

Comments
 (0)