Skip to content

Commit 1bafc37

Browse files
jahay1roxanan1996
authored andcommitted
idpf: stop Tx if there are insufficient buffer resources
jira KERNEL-170 commit-author Joshua Hay <joshua.a.hay@intel.com> commit 0c3f135 upstream-diff | adjusted conflict in idpf_tx_splitq_frame func due to missing 1a49cf8 ("idpf: add Tx timestamp flows"). The Tx refillq logic will cause packets to be silently dropped if there are not enough buffer resources available to send a packet in flow scheduling mode. Instead, determine how many buffers are needed along with number of descriptors. Make sure there are enough of both resources to send the packet, and stop the queue if not. Fixes: 7292af0 ("idpf: fix a race in txq wakeup") Signed-off-by: Joshua Hay <joshua.a.hay@intel.com> Reviewed-by: Madhu Chittim <madhu.chittim@intel.com> Tested-by: Samuel Salin <Samuel.salin@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> (cherry picked from commit 0c3f135) Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 4ea8eb9 commit 1bafc37

3 files changed

Lines changed: 47 additions & 19 deletions

File tree

drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,11 +415,11 @@ netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
415415
{
416416
struct idpf_tx_offload_params offload = { };
417417
struct idpf_tx_buf *first;
418+
u32 count, buf_count = 1;
418419
int csum, tso, needed;
419-
unsigned int count;
420420
__be16 protocol;
421421

422-
count = idpf_tx_desc_count_required(tx_q, skb);
422+
count = idpf_tx_res_count_required(tx_q, skb, &buf_count);
423423
if (unlikely(!count))
424424
return idpf_tx_drop_skb(tx_q, skb);
425425

drivers/net/ethernet/intel/idpf/idpf_txrx.c

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,15 +2140,22 @@ void idpf_tx_splitq_build_flow_desc(union idpf_tx_flex_desc *desc,
21402140
desc->flow.qw1.compl_tag = cpu_to_le16(params->compl_tag);
21412141
}
21422142

2143-
/* Global conditions to tell whether the txq (and related resources)
2144-
* has room to allow the use of "size" descriptors.
2143+
/**
2144+
* idpf_tx_splitq_has_room - check if enough Tx splitq resources are available
2145+
* @tx_q: the queue to be checked
2146+
* @descs_needed: number of descriptors required for this packet
2147+
* @bufs_needed: number of Tx buffers required for this packet
2148+
*
2149+
* Return: 0 if no room available, 1 otherwise
21452150
*/
2146-
static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
2151+
static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 descs_needed,
2152+
u32 bufs_needed)
21472153
{
2148-
if (IDPF_DESC_UNUSED(tx_q) < size ||
2154+
if (IDPF_DESC_UNUSED(tx_q) < descs_needed ||
21492155
IDPF_TX_COMPLQ_PENDING(tx_q->txq_grp) >
21502156
IDPF_TX_COMPLQ_OVERFLOW_THRESH(tx_q->txq_grp->complq) ||
2151-
IDPF_TX_BUF_RSV_LOW(tx_q))
2157+
IDPF_TX_BUF_RSV_LOW(tx_q) ||
2158+
idpf_tx_splitq_get_free_bufs(tx_q->refillq) < bufs_needed)
21522159
return 0;
21532160
return 1;
21542161
}
@@ -2157,14 +2164,21 @@ static int idpf_txq_has_room(struct idpf_tx_queue *tx_q, u32 size)
21572164
* idpf_tx_maybe_stop_splitq - 1st level check for Tx splitq stop conditions
21582165
* @tx_q: the queue to be checked
21592166
* @descs_needed: number of descriptors required for this packet
2167+
* @bufs_needed: number of buffers needed for this packet
21602168
*
2161-
* Returns 0 if stop is not needed
2169+
* Return: 0 if stop is not needed
21622170
*/
21632171
static int idpf_tx_maybe_stop_splitq(struct idpf_tx_queue *tx_q,
2164-
unsigned int descs_needed)
2172+
u32 descs_needed,
2173+
u32 bufs_needed)
21652174
{
2175+
/* Since we have multiple resources to check for splitq, our
2176+
* start,stop_thrs becomes a boolean check instead of a count
2177+
* threshold.
2178+
*/
21662179
if (netif_subqueue_maybe_stop(tx_q->netdev, tx_q->idx,
2167-
idpf_txq_has_room(tx_q, descs_needed),
2180+
idpf_txq_has_room(tx_q, descs_needed,
2181+
bufs_needed),
21682182
1, 1))
21692183
return 0;
21702184

@@ -2206,14 +2220,16 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
22062220
}
22072221

22082222
/**
2209-
* idpf_tx_desc_count_required - calculate number of Tx descriptors needed
2223+
* idpf_tx_res_count_required - get number of Tx resources needed for this pkt
22102224
* @txq: queue to send buffer on
22112225
* @skb: send buffer
2226+
* @bufs_needed: (output) number of buffers needed for this skb.
22122227
*
2213-
* Returns number of data descriptors needed for this skb.
2228+
* Return: number of data descriptors and buffers needed for this skb.
22142229
*/
2215-
unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
2216-
struct sk_buff *skb)
2230+
unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq,
2231+
struct sk_buff *skb,
2232+
u32 *bufs_needed)
22172233
{
22182234
const struct skb_shared_info *shinfo;
22192235
unsigned int count = 0, i;
@@ -2224,6 +2240,7 @@ unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
22242240
return count;
22252241

22262242
shinfo = skb_shinfo(skb);
2243+
*bufs_needed += shinfo->nr_frags;
22272244
for (i = 0; i < shinfo->nr_frags; i++) {
22282245
unsigned int size;
22292246

@@ -2773,11 +2790,11 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
27732790
.prev_ntu = tx_q->next_to_use,
27742791
};
27752792
struct idpf_tx_buf *first;
2776-
unsigned int count;
2793+
u32 count, buf_count = 1;
27772794
int tso;
27782795
u32 buf_id;
27792796

2780-
count = idpf_tx_desc_count_required(tx_q, skb);
2797+
count = idpf_tx_res_count_required(tx_q, skb, &buf_count);
27812798
if (unlikely(!count))
27822799
return idpf_tx_drop_skb(tx_q, skb);
27832800

@@ -2787,7 +2804,7 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
27872804

27882805
/* Check for splitq specific TX resources */
27892806
count += (IDPF_TX_DESCS_PER_CACHE_LINE + tso);
2790-
if (idpf_tx_maybe_stop_splitq(tx_q, count)) {
2807+
if (idpf_tx_maybe_stop_splitq(tx_q, count, buf_count)) {
27912808
idpf_tx_buf_hw_update(tx_q, tx_q->next_to_use, false);
27922809

27932810
return NETDEV_TX_BUSY;

drivers/net/ethernet/intel/idpf/idpf_txrx.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,17 @@ static inline void idpf_vport_intr_set_wb_on_itr(struct idpf_q_vector *q_vector)
10151015
reg->dyn_ctl);
10161016
}
10171017

1018+
/**
1019+
* idpf_tx_splitq_get_free_bufs - get number of free buf_ids in refillq
1020+
* @refillq: pointer to refillq containing buf_ids
1021+
*/
1022+
static inline u32 idpf_tx_splitq_get_free_bufs(struct idpf_sw_queue *refillq)
1023+
{
1024+
return (refillq->next_to_use > refillq->next_to_clean ?
1025+
0 : refillq->desc_count) +
1026+
refillq->next_to_use - refillq->next_to_clean - 1;
1027+
}
1028+
10181029
int idpf_vport_singleq_napi_poll(struct napi_struct *napi, int budget);
10191030
void idpf_vport_init_num_qs(struct idpf_vport *vport,
10201031
struct virtchnl2_create_vport *vport_msg);
@@ -1042,8 +1053,8 @@ void idpf_tx_buf_hw_update(struct idpf_tx_queue *tx_q, u32 val,
10421053
bool xmit_more);
10431054
unsigned int idpf_size_to_txd_count(unsigned int size);
10441055
netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb);
1045-
unsigned int idpf_tx_desc_count_required(struct idpf_tx_queue *txq,
1046-
struct sk_buff *skb);
1056+
unsigned int idpf_tx_res_count_required(struct idpf_tx_queue *txq,
1057+
struct sk_buff *skb, u32 *buf_count);
10471058
void idpf_tx_timeout(struct net_device *netdev, unsigned int txqueue);
10481059
netdev_tx_t idpf_tx_singleq_frame(struct sk_buff *skb,
10491060
struct idpf_tx_queue *tx_q);

0 commit comments

Comments
 (0)