Skip to content

Commit 02614ee

Browse files
edumazetkuba-moo
authored andcommitted
idpf: do not linearize big TSO packets
idpf has a limit on number of scatter-gather frags that can be used per segment. Currently, idpf_tx_start() checks if the limit is hit and forces a linearization of the whole packet. This requires high order allocations that can fail under memory pressure. A full size BIG-TCP packet would require order-7 alocation on x86_64 :/ We can move the check earlier from idpf_features_check() for TSO packets, to force GSO in this case, removing the cost of a big copy. This means that a linearization will eventually happen with sizes smaller than one MSS. __idpf_chk_linearize() is renamed to idpf_chk_tso_segment() and moved to idpf_lib.c Signed-off-by: Eric Dumazet <[email protected]> Cc: Przemek Kitszel <[email protected]> Cc: Jacob Keller <[email protected]> Cc: Madhu Chittim <[email protected]> Cc: Pavan Kumar Linga <[email protected]> Cc: Willem de Bruijn <[email protected]> Cc: Andrew Lunn <[email protected]> Reviewed-by: Joshua Hay <[email protected]> Tested-by: Brian Vazquez <[email protected]> Acked-by: Tony Nguyen <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent cd31182 commit 02614ee

File tree

3 files changed

+120
-113
lines changed

3 files changed

+120
-113
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ enum idpf_vport_state {
148148
* @link_speed_mbps: Link speed in mbps
149149
* @vport_idx: Relative vport index
150150
* @max_tx_hdr_size: Max header length hardware can support
151+
* @tx_max_bufs: Max buffers that can be transmitted with scatter-gather
151152
* @state: See enum idpf_vport_state
152153
* @netstats: Packet and byte stats
153154
* @stats_lock: Lock to protect stats update
@@ -159,6 +160,7 @@ struct idpf_netdev_priv {
159160
u32 link_speed_mbps;
160161
u16 vport_idx;
161162
u16 max_tx_hdr_size;
163+
u16 tx_max_bufs;
162164
enum idpf_vport_state state;
163165
struct rtnl_link_stats64 netstats;
164166
spinlock_t stats_lock;

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

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ static int idpf_cfg_netdev(struct idpf_vport *vport)
776776
np->vport_idx = vport->idx;
777777
np->vport_id = vport->vport_id;
778778
np->max_tx_hdr_size = idpf_get_max_tx_hdr_size(adapter);
779+
np->tx_max_bufs = idpf_get_max_tx_bufs(adapter);
779780

780781
spin_lock_init(&np->stats_lock);
781782

@@ -2271,6 +2272,92 @@ static int idpf_change_mtu(struct net_device *netdev, int new_mtu)
22712272
return err;
22722273
}
22732274

2275+
/**
2276+
* idpf_chk_tso_segment - Check skb is not using too many buffers
2277+
* @skb: send buffer
2278+
* @max_bufs: maximum number of buffers
2279+
*
2280+
* For TSO we need to count the TSO header and segment payload separately. As
2281+
* such we need to check cases where we have max_bufs-1 fragments or more as we
2282+
* can potentially require max_bufs+1 DMA transactions, 1 for the TSO header, 1
2283+
* for the segment payload in the first descriptor, and another max_buf-1 for
2284+
* the fragments.
2285+
*
2286+
* Returns true if the packet needs to be software segmented by core stack.
2287+
*/
2288+
static bool idpf_chk_tso_segment(const struct sk_buff *skb,
2289+
unsigned int max_bufs)
2290+
{
2291+
const struct skb_shared_info *shinfo = skb_shinfo(skb);
2292+
const skb_frag_t *frag, *stale;
2293+
int nr_frags, sum;
2294+
2295+
/* no need to check if number of frags is less than max_bufs - 1 */
2296+
nr_frags = shinfo->nr_frags;
2297+
if (nr_frags < (max_bufs - 1))
2298+
return false;
2299+
2300+
/* We need to walk through the list and validate that each group
2301+
* of max_bufs-2 fragments totals at least gso_size.
2302+
*/
2303+
nr_frags -= max_bufs - 2;
2304+
frag = &shinfo->frags[0];
2305+
2306+
/* Initialize size to the negative value of gso_size minus 1. We use
2307+
* this as the worst case scenario in which the frag ahead of us only
2308+
* provides one byte which is why we are limited to max_bufs-2
2309+
* descriptors for a single transmit as the header and previous
2310+
* fragment are already consuming 2 descriptors.
2311+
*/
2312+
sum = 1 - shinfo->gso_size;
2313+
2314+
/* Add size of frags 0 through 4 to create our initial sum */
2315+
sum += skb_frag_size(frag++);
2316+
sum += skb_frag_size(frag++);
2317+
sum += skb_frag_size(frag++);
2318+
sum += skb_frag_size(frag++);
2319+
sum += skb_frag_size(frag++);
2320+
2321+
/* Walk through fragments adding latest fragment, testing it, and
2322+
* then removing stale fragments from the sum.
2323+
*/
2324+
for (stale = &shinfo->frags[0];; stale++) {
2325+
int stale_size = skb_frag_size(stale);
2326+
2327+
sum += skb_frag_size(frag++);
2328+
2329+
/* The stale fragment may present us with a smaller
2330+
* descriptor than the actual fragment size. To account
2331+
* for that we need to remove all the data on the front and
2332+
* figure out what the remainder would be in the last
2333+
* descriptor associated with the fragment.
2334+
*/
2335+
if (stale_size > IDPF_TX_MAX_DESC_DATA) {
2336+
int align_pad = -(skb_frag_off(stale)) &
2337+
(IDPF_TX_MAX_READ_REQ_SIZE - 1);
2338+
2339+
sum -= align_pad;
2340+
stale_size -= align_pad;
2341+
2342+
do {
2343+
sum -= IDPF_TX_MAX_DESC_DATA_ALIGNED;
2344+
stale_size -= IDPF_TX_MAX_DESC_DATA_ALIGNED;
2345+
} while (stale_size > IDPF_TX_MAX_DESC_DATA);
2346+
}
2347+
2348+
/* if sum is negative we failed to make sufficient progress */
2349+
if (sum < 0)
2350+
return true;
2351+
2352+
if (!nr_frags--)
2353+
break;
2354+
2355+
sum -= stale_size;
2356+
}
2357+
2358+
return false;
2359+
}
2360+
22742361
/**
22752362
* idpf_features_check - Validate packet conforms to limits
22762363
* @skb: skb buffer
@@ -2292,12 +2379,15 @@ static netdev_features_t idpf_features_check(struct sk_buff *skb,
22922379
if (skb->ip_summed != CHECKSUM_PARTIAL)
22932380
return features;
22942381

2295-
/* We cannot support GSO if the MSS is going to be less than
2296-
* 88 bytes. If it is then we need to drop support for GSO.
2297-
*/
2298-
if (skb_is_gso(skb) &&
2299-
(skb_shinfo(skb)->gso_size < IDPF_TX_TSO_MIN_MSS))
2300-
features &= ~NETIF_F_GSO_MASK;
2382+
if (skb_is_gso(skb)) {
2383+
/* We cannot support GSO if the MSS is going to be less than
2384+
* 88 bytes. If it is then we need to drop support for GSO.
2385+
*/
2386+
if (skb_shinfo(skb)->gso_size < IDPF_TX_TSO_MIN_MSS)
2387+
features &= ~NETIF_F_GSO_MASK;
2388+
else if (idpf_chk_tso_segment(skb, np->tx_max_bufs))
2389+
features &= ~NETIF_F_GSO_MASK;
2390+
}
23012391

23022392
/* Ensure MACLEN is <= 126 bytes (63 words) and not an odd size */
23032393
len = skb_network_offset(skb);

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

Lines changed: 22 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,28 @@ struct idpf_tx_stash {
1616
#define idpf_tx_buf_compl_tag(buf) (*(u32 *)&(buf)->priv)
1717
LIBETH_SQE_CHECK_PRIV(u32);
1818

19-
static bool idpf_chk_linearize(struct sk_buff *skb, unsigned int max_bufs,
20-
unsigned int count);
19+
/**
20+
* idpf_chk_linearize - Check if skb exceeds max descriptors per packet
21+
* @skb: send buffer
22+
* @max_bufs: maximum scatter gather buffers for single packet
23+
* @count: number of buffers this packet needs
24+
*
25+
* Make sure we don't exceed maximum scatter gather buffers for a single
26+
* packet.
27+
* TSO case has been handled earlier from idpf_features_check().
28+
*/
29+
static bool idpf_chk_linearize(const struct sk_buff *skb,
30+
unsigned int max_bufs,
31+
unsigned int count)
32+
{
33+
if (likely(count <= max_bufs))
34+
return false;
35+
36+
if (skb_is_gso(skb))
37+
return false;
38+
39+
return true;
40+
}
2141

2242
/**
2343
* idpf_buf_lifo_push - push a buffer pointer onto stack
@@ -2627,111 +2647,6 @@ int idpf_tso(struct sk_buff *skb, struct idpf_tx_offload_params *off)
26272647
return 1;
26282648
}
26292649

2630-
/**
2631-
* __idpf_chk_linearize - Check skb is not using too many buffers
2632-
* @skb: send buffer
2633-
* @max_bufs: maximum number of buffers
2634-
*
2635-
* For TSO we need to count the TSO header and segment payload separately. As
2636-
* such we need to check cases where we have max_bufs-1 fragments or more as we
2637-
* can potentially require max_bufs+1 DMA transactions, 1 for the TSO header, 1
2638-
* for the segment payload in the first descriptor, and another max_buf-1 for
2639-
* the fragments.
2640-
*/
2641-
static bool __idpf_chk_linearize(struct sk_buff *skb, unsigned int max_bufs)
2642-
{
2643-
const struct skb_shared_info *shinfo = skb_shinfo(skb);
2644-
const skb_frag_t *frag, *stale;
2645-
int nr_frags, sum;
2646-
2647-
/* no need to check if number of frags is less than max_bufs - 1 */
2648-
nr_frags = shinfo->nr_frags;
2649-
if (nr_frags < (max_bufs - 1))
2650-
return false;
2651-
2652-
/* We need to walk through the list and validate that each group
2653-
* of max_bufs-2 fragments totals at least gso_size.
2654-
*/
2655-
nr_frags -= max_bufs - 2;
2656-
frag = &shinfo->frags[0];
2657-
2658-
/* Initialize size to the negative value of gso_size minus 1. We use
2659-
* this as the worst case scenario in which the frag ahead of us only
2660-
* provides one byte which is why we are limited to max_bufs-2
2661-
* descriptors for a single transmit as the header and previous
2662-
* fragment are already consuming 2 descriptors.
2663-
*/
2664-
sum = 1 - shinfo->gso_size;
2665-
2666-
/* Add size of frags 0 through 4 to create our initial sum */
2667-
sum += skb_frag_size(frag++);
2668-
sum += skb_frag_size(frag++);
2669-
sum += skb_frag_size(frag++);
2670-
sum += skb_frag_size(frag++);
2671-
sum += skb_frag_size(frag++);
2672-
2673-
/* Walk through fragments adding latest fragment, testing it, and
2674-
* then removing stale fragments from the sum.
2675-
*/
2676-
for (stale = &shinfo->frags[0];; stale++) {
2677-
int stale_size = skb_frag_size(stale);
2678-
2679-
sum += skb_frag_size(frag++);
2680-
2681-
/* The stale fragment may present us with a smaller
2682-
* descriptor than the actual fragment size. To account
2683-
* for that we need to remove all the data on the front and
2684-
* figure out what the remainder would be in the last
2685-
* descriptor associated with the fragment.
2686-
*/
2687-
if (stale_size > IDPF_TX_MAX_DESC_DATA) {
2688-
int align_pad = -(skb_frag_off(stale)) &
2689-
(IDPF_TX_MAX_READ_REQ_SIZE - 1);
2690-
2691-
sum -= align_pad;
2692-
stale_size -= align_pad;
2693-
2694-
do {
2695-
sum -= IDPF_TX_MAX_DESC_DATA_ALIGNED;
2696-
stale_size -= IDPF_TX_MAX_DESC_DATA_ALIGNED;
2697-
} while (stale_size > IDPF_TX_MAX_DESC_DATA);
2698-
}
2699-
2700-
/* if sum is negative we failed to make sufficient progress */
2701-
if (sum < 0)
2702-
return true;
2703-
2704-
if (!nr_frags--)
2705-
break;
2706-
2707-
sum -= stale_size;
2708-
}
2709-
2710-
return false;
2711-
}
2712-
2713-
/**
2714-
* idpf_chk_linearize - Check if skb exceeds max descriptors per packet
2715-
* @skb: send buffer
2716-
* @max_bufs: maximum scatter gather buffers for single packet
2717-
* @count: number of buffers this packet needs
2718-
*
2719-
* Make sure we don't exceed maximum scatter gather buffers for a single
2720-
* packet. We have to do some special checking around the boundary (max_bufs-1)
2721-
* if TSO is on since we need count the TSO header and payload separately.
2722-
* E.g.: a packet with 7 fragments can require 9 DMA transactions; 1 for TSO
2723-
* header, 1 for segment payload, and then 7 for the fragments.
2724-
*/
2725-
static bool idpf_chk_linearize(struct sk_buff *skb, unsigned int max_bufs,
2726-
unsigned int count)
2727-
{
2728-
if (likely(count < max_bufs))
2729-
return false;
2730-
if (skb_is_gso(skb))
2731-
return __idpf_chk_linearize(skb, max_bufs);
2732-
2733-
return count > max_bufs;
2734-
}
27352650

27362651
/**
27372652
* idpf_tx_splitq_get_ctx_desc - grab next desc and update buffer ring

0 commit comments

Comments
 (0)