1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2015 Intel Corporation
9 #include "virtio_logs.h"
10 #include "virtio_pci.h"
11 #include "virtio_rxtx_simple.h"
14 * Two types of mbuf to be cleaned:
15 * 1) mbuf that has been consumed by backend but not used by virtio.
16 * 2) mbuf that hasn't been consued by backend.
19 virtqueue_detach_unused(struct virtqueue
*vq
)
21 struct rte_mbuf
*cookie
;
30 type
= virtio_get_queue_type(hw
, vq
->vq_queue_index
);
31 start
= vq
->vq_avail_idx
& (vq
->vq_nentries
- 1);
32 end
= (vq
->vq_avail_idx
+ vq
->vq_free_cnt
) & (vq
->vq_nentries
- 1);
34 for (idx
= 0; idx
< vq
->vq_nentries
; idx
++) {
35 if (hw
->use_simple_rx
&& type
== VTNET_RQ
) {
36 if (start
<= end
&& idx
>= start
&& idx
< end
)
38 if (start
> end
&& (idx
>= start
|| idx
< end
))
40 cookie
= vq
->sw_ring
[idx
];
42 vq
->sw_ring
[idx
] = NULL
;
46 cookie
= vq
->vq_descx
[idx
].cookie
;
48 vq
->vq_descx
[idx
].cookie
= NULL
;
57 /* Flush the elements in the used ring. */
59 virtqueue_rxvq_flush(struct virtqueue
*vq
)
61 struct virtnet_rx
*rxq
= &vq
->rxq
;
62 struct virtio_hw
*hw
= vq
->hw
;
63 struct vring_used_elem
*uep
;
64 struct vq_desc_extra
*dxp
;
65 uint16_t used_idx
, desc_idx
;
68 nb_used
= VIRTQUEUE_NUSED(vq
);
70 for (i
= 0; i
< nb_used
; i
++) {
71 used_idx
= vq
->vq_used_cons_idx
& (vq
->vq_nentries
- 1);
72 uep
= &vq
->vq_ring
.used
->ring
[used_idx
];
73 if (hw
->use_simple_rx
) {
75 rte_pktmbuf_free(vq
->sw_ring
[desc_idx
]);
77 } else if (hw
->use_inorder_rx
) {
78 desc_idx
= (uint16_t)uep
->id
;
79 dxp
= &vq
->vq_descx
[desc_idx
];
80 if (dxp
->cookie
!= NULL
) {
81 rte_pktmbuf_free(dxp
->cookie
);
84 vq_ring_free_inorder(vq
, desc_idx
, 1);
86 desc_idx
= (uint16_t)uep
->id
;
87 dxp
= &vq
->vq_descx
[desc_idx
];
88 if (dxp
->cookie
!= NULL
) {
89 rte_pktmbuf_free(dxp
->cookie
);
92 vq_ring_free_chain(vq
, desc_idx
);
94 vq
->vq_used_cons_idx
++;
97 if (hw
->use_simple_rx
) {
98 while (vq
->vq_free_cnt
>= RTE_VIRTIO_VPMD_RX_REARM_THRESH
) {
99 virtio_rxq_rearm_vec(rxq
);
100 if (virtqueue_kick_prepare(vq
))
101 virtqueue_notify(vq
);