Skip to content

Commit b07a2d9

Browse files
committed
net: skb: plumb napi state thru skb freeing paths
We maintain a NAPI-local cache of skbs which is fed by napi_consume_skb(). Going forward we will also try to cache head and data pages. Plumb the "are we in a normal NAPI context" information thru deeper into the freeing path, up to skb_release_data() and skb_free_head()/skb_pp_recycle(). The "not normal NAPI context" comes from netpoll which passes budget of 0 to try to reap the Tx completions but not perform any Rx. Use "bool napi_safe" rather than bare "int budget", the further we get from NAPI the more confusing the budget argument may seem (particularly whether 0 or MAX is the correct value to pass in when not in NAPI). Reviewed-by: Tariq Toukan <[email protected]> Tested-by: Dragos Tatulea <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c11d2e7 commit b07a2d9

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

net/core/skbuff.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static void skb_clone_fraglist(struct sk_buff *skb)
839839
skb_get(list);
840840
}
841841

842-
static bool skb_pp_recycle(struct sk_buff *skb, void *data)
842+
static bool skb_pp_recycle(struct sk_buff *skb, void *data, bool napi_safe)
843843
{
844844
if (!IS_ENABLED(CONFIG_PAGE_POOL) || !skb->pp_recycle)
845845
return false;
@@ -856,20 +856,21 @@ static void skb_kfree_head(void *head, unsigned int end_offset)
856856
kfree(head);
857857
}
858858

859-
static void skb_free_head(struct sk_buff *skb)
859+
static void skb_free_head(struct sk_buff *skb, bool napi_safe)
860860
{
861861
unsigned char *head = skb->head;
862862

863863
if (skb->head_frag) {
864-
if (skb_pp_recycle(skb, head))
864+
if (skb_pp_recycle(skb, head, napi_safe))
865865
return;
866866
skb_free_frag(head);
867867
} else {
868868
skb_kfree_head(head, skb_end_offset(skb));
869869
}
870870
}
871871

872-
static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason)
872+
static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason,
873+
bool napi_safe)
873874
{
874875
struct skb_shared_info *shinfo = skb_shinfo(skb);
875876
int i;
@@ -894,7 +895,7 @@ static void skb_release_data(struct sk_buff *skb, enum skb_drop_reason reason)
894895
if (shinfo->frag_list)
895896
kfree_skb_list_reason(shinfo->frag_list, reason);
896897

897-
skb_free_head(skb);
898+
skb_free_head(skb, napi_safe);
898899
exit:
899900
/* When we clone an SKB we copy the reycling bit. The pp_recycle
900901
* bit is only set on the head though, so in order to avoid races
@@ -955,11 +956,12 @@ void skb_release_head_state(struct sk_buff *skb)
955956
}
956957

957958
/* Free everything but the sk_buff shell. */
958-
static void skb_release_all(struct sk_buff *skb, enum skb_drop_reason reason)
959+
static void skb_release_all(struct sk_buff *skb, enum skb_drop_reason reason,
960+
bool napi_safe)
959961
{
960962
skb_release_head_state(skb);
961963
if (likely(skb->head))
962-
skb_release_data(skb, reason);
964+
skb_release_data(skb, reason, napi_safe);
963965
}
964966

965967
/**
@@ -973,7 +975,7 @@ static void skb_release_all(struct sk_buff *skb, enum skb_drop_reason reason)
973975

974976
void __kfree_skb(struct sk_buff *skb)
975977
{
976-
skb_release_all(skb, SKB_DROP_REASON_NOT_SPECIFIED);
978+
skb_release_all(skb, SKB_DROP_REASON_NOT_SPECIFIED, false);
977979
kfree_skbmem(skb);
978980
}
979981
EXPORT_SYMBOL(__kfree_skb);
@@ -1027,7 +1029,7 @@ static void kfree_skb_add_bulk(struct sk_buff *skb,
10271029
return;
10281030
}
10291031

1030-
skb_release_all(skb, reason);
1032+
skb_release_all(skb, reason, false);
10311033
sa->skb_array[sa->skb_count++] = skb;
10321034

10331035
if (unlikely(sa->skb_count == KFREE_SKB_BULK_SIZE)) {
@@ -1201,7 +1203,7 @@ EXPORT_SYMBOL(consume_skb);
12011203
void __consume_stateless_skb(struct sk_buff *skb)
12021204
{
12031205
trace_consume_skb(skb, __builtin_return_address(0));
1204-
skb_release_data(skb, SKB_CONSUMED);
1206+
skb_release_data(skb, SKB_CONSUMED, false);
12051207
kfree_skbmem(skb);
12061208
}
12071209

@@ -1226,7 +1228,7 @@ static void napi_skb_cache_put(struct sk_buff *skb)
12261228

12271229
void __kfree_skb_defer(struct sk_buff *skb)
12281230
{
1229-
skb_release_all(skb, SKB_DROP_REASON_NOT_SPECIFIED);
1231+
skb_release_all(skb, SKB_DROP_REASON_NOT_SPECIFIED, true);
12301232
napi_skb_cache_put(skb);
12311233
}
12321234

@@ -1264,7 +1266,7 @@ void napi_consume_skb(struct sk_buff *skb, int budget)
12641266
return;
12651267
}
12661268

1267-
skb_release_all(skb, SKB_CONSUMED);
1269+
skb_release_all(skb, SKB_CONSUMED, !!budget);
12681270
napi_skb_cache_put(skb);
12691271
}
12701272
EXPORT_SYMBOL(napi_consume_skb);
@@ -1395,7 +1397,7 @@ EXPORT_SYMBOL_GPL(alloc_skb_for_msg);
13951397
*/
13961398
struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src)
13971399
{
1398-
skb_release_all(dst, SKB_CONSUMED);
1400+
skb_release_all(dst, SKB_CONSUMED, false);
13991401
return __skb_clone(dst, src);
14001402
}
14011403
EXPORT_SYMBOL_GPL(skb_morph);
@@ -2018,9 +2020,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
20182020
if (skb_has_frag_list(skb))
20192021
skb_clone_fraglist(skb);
20202022

2021-
skb_release_data(skb, SKB_CONSUMED);
2023+
skb_release_data(skb, SKB_CONSUMED, false);
20222024
} else {
2023-
skb_free_head(skb);
2025+
skb_free_head(skb, false);
20242026
}
20252027
off = (data + nhead) - skb->head;
20262028

@@ -6389,12 +6391,12 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
63896391
skb_frag_ref(skb, i);
63906392
if (skb_has_frag_list(skb))
63916393
skb_clone_fraglist(skb);
6392-
skb_release_data(skb, SKB_CONSUMED);
6394+
skb_release_data(skb, SKB_CONSUMED, false);
63936395
} else {
63946396
/* we can reuse existing recount- all we did was
63956397
* relocate values
63966398
*/
6397-
skb_free_head(skb);
6399+
skb_free_head(skb, false);
63986400
}
63996401

64006402
skb->head = data;
@@ -6529,7 +6531,7 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
65296531
skb_kfree_head(data, size);
65306532
return -ENOMEM;
65316533
}
6532-
skb_release_data(skb, SKB_CONSUMED);
6534+
skb_release_data(skb, SKB_CONSUMED, false);
65336535

65346536
skb->head = data;
65356537
skb->head_frag = 0;

0 commit comments

Comments
 (0)