aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorOctavian Purdila <octavian.purdila@intel.com>2014-06-11 18:36:26 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-11 18:38:02 -0400
commitbad93e9d4eeb0d2d6b79204d6cedc7f2e7b256f1 (patch)
tree816931467196e2a89ac47919bfb2b2fc45969209 /net
parent1a0b20b257326523ec2a6cb51dd6f26ef179eb84 (diff)
net: add __pskb_copy_fclone and pskb_copy_for_clone
There are several instances where a pskb_copy or __pskb_copy is immediately followed by an skb_clone. Add a couple of new functions to allow the copy skb to be allocated from the fclone cache and thus speed up subsequent skb_clone calls. Cc: Alexander Smirnov <alex.bluesman.smirnov@gmail.com> Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> Cc: Marek Lindner <mareklindner@neomailbox.ch> Cc: Simon Wunderlich <sw@simonwunderlich.de> Cc: Antonio Quartulli <antonio@meshcoding.com> Cc: Marcel Holtmann <marcel@holtmann.org> Cc: Gustavo Padovan <gustavo@padovan.org> Cc: Johan Hedberg <johan.hedberg@gmail.com> Cc: Arvid Brodin <arvid.brodin@alten.se> Cc: Patrick McHardy <kaber@trash.net> Cc: Pablo Neira Ayuso <pablo@netfilter.org> Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Cc: Lauro Ramos Venancio <lauro.venancio@openbossa.org> Cc: Aloisio Almeida Jr <aloisio.almeida@openbossa.org> Cc: Samuel Ortiz <sameo@linux.intel.com> Cc: Jon Maloy <jon.maloy@ericsson.com> Cc: Allan Stephens <allan.stephens@windriver.com> Cc: Andrew Hendry <andrew.hendry@gmail.com> Cc: Eric Dumazet <edumazet@google.com> Reviewed-by: Christoph Paasch <christoph.paasch@uclouvain.be> Signed-off-by: Octavian Purdila <octavian.purdila@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/distributed-arp-table.c2
-rw-r--r--net/batman-adv/network-coding.c2
-rw-r--r--net/bluetooth/hci_sock.c6
-rw-r--r--net/core/skbuff.c14
-rw-r--r--net/nfc/llcp_core.c4
-rw-r--r--net/nfc/rawsock.c4
-rw-r--r--net/tipc/bcast.c2
7 files changed, 19 insertions, 15 deletions
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index dcd99b2bea3c..f2c066b21716 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -594,7 +594,7 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
594 if (!neigh_node) 594 if (!neigh_node)
595 goto free_orig; 595 goto free_orig;
596 596
597 tmp_skb = pskb_copy(skb, GFP_ATOMIC); 597 tmp_skb = pskb_copy_for_clone(skb, GFP_ATOMIC);
598 if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb, 598 if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb,
599 cand[i].orig_node, 599 cand[i].orig_node,
600 packet_subtype)) { 600 packet_subtype)) {
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index 40a2fc4bcf4c..8d04d174669e 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -1344,7 +1344,7 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv,
1344 struct ethhdr *ethhdr; 1344 struct ethhdr *ethhdr;
1345 1345
1346 /* Copy skb header to change the mac header */ 1346 /* Copy skb header to change the mac header */
1347 skb = pskb_copy(skb, GFP_ATOMIC); 1347 skb = pskb_copy_for_clone(skb, GFP_ATOMIC);
1348 if (!skb) 1348 if (!skb)
1349 return; 1349 return;
1350 1350
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index f608bffdb8b9..80d25c150a65 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -143,7 +143,7 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
143 143
144 if (!skb_copy) { 144 if (!skb_copy) {
145 /* Create a private copy with headroom */ 145 /* Create a private copy with headroom */
146 skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC); 146 skb_copy = __pskb_copy_fclone(skb, 1, GFP_ATOMIC, true);
147 if (!skb_copy) 147 if (!skb_copy)
148 continue; 148 continue;
149 149
@@ -247,8 +247,8 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
247 struct hci_mon_hdr *hdr; 247 struct hci_mon_hdr *hdr;
248 248
249 /* Create a private copy with headroom */ 249 /* Create a private copy with headroom */
250 skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, 250 skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE,
251 GFP_ATOMIC); 251 GFP_ATOMIC, true);
252 if (!skb_copy) 252 if (!skb_copy)
253 continue; 253 continue;
254 254
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 05f4bef2ce12..b9e85e6cb26a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -951,10 +951,13 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
951EXPORT_SYMBOL(skb_copy); 951EXPORT_SYMBOL(skb_copy);
952 952
953/** 953/**
954 * __pskb_copy - create copy of an sk_buff with private head. 954 * __pskb_copy_fclone - create copy of an sk_buff with private head.
955 * @skb: buffer to copy 955 * @skb: buffer to copy
956 * @headroom: headroom of new skb 956 * @headroom: headroom of new skb
957 * @gfp_mask: allocation priority 957 * @gfp_mask: allocation priority
958 * @fclone: if true allocate the copy of the skb from the fclone
959 * cache instead of the head cache; it is recommended to set this
960 * to true for the cases where the copy will likely be cloned
958 * 961 *
959 * Make a copy of both an &sk_buff and part of its data, located 962 * Make a copy of both an &sk_buff and part of its data, located
960 * in header. Fragmented data remain shared. This is used when 963 * in header. Fragmented data remain shared. This is used when
@@ -964,11 +967,12 @@ EXPORT_SYMBOL(skb_copy);
964 * The returned buffer has a reference count of 1. 967 * The returned buffer has a reference count of 1.
965 */ 968 */
966 969
967struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask) 970struct sk_buff *__pskb_copy_fclone(struct sk_buff *skb, int headroom,
971 gfp_t gfp_mask, bool fclone)
968{ 972{
969 unsigned int size = skb_headlen(skb) + headroom; 973 unsigned int size = skb_headlen(skb) + headroom;
970 struct sk_buff *n = __alloc_skb(size, gfp_mask, 974 int flags = skb_alloc_rx_flag(skb) | (fclone ? SKB_ALLOC_FCLONE : 0);
971 skb_alloc_rx_flag(skb), NUMA_NO_NODE); 975 struct sk_buff *n = __alloc_skb(size, gfp_mask, flags, NUMA_NO_NODE);
972 976
973 if (!n) 977 if (!n)
974 goto out; 978 goto out;
@@ -1008,7 +1012,7 @@ struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
1008out: 1012out:
1009 return n; 1013 return n;
1010} 1014}
1011EXPORT_SYMBOL(__pskb_copy); 1015EXPORT_SYMBOL(__pskb_copy_fclone);
1012 1016
1013/** 1017/**
1014 * pskb_expand_head - reallocate header of &sk_buff 1018 * pskb_expand_head - reallocate header of &sk_buff
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index f6278da68763..51e788797317 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -680,8 +680,8 @@ void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
680 continue; 680 continue;
681 681
682 if (skb_copy == NULL) { 682 if (skb_copy == NULL) {
683 skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE, 683 skb_copy = __pskb_copy_fclone(skb, NFC_RAW_HEADER_SIZE,
684 GFP_ATOMIC); 684 GFP_ATOMIC, true);
685 685
686 if (skb_copy == NULL) 686 if (skb_copy == NULL)
687 continue; 687 continue;
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index 55eefee311eb..11c3544ea546 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -378,8 +378,8 @@ void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb,
378 378
379 sk_for_each(sk, &raw_sk_list.head) { 379 sk_for_each(sk, &raw_sk_list.head) {
380 if (!skb_copy) { 380 if (!skb_copy) {
381 skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE, 381 skb_copy = __pskb_copy_fclone(skb, NFC_RAW_HEADER_SIZE,
382 GFP_ATOMIC); 382 GFP_ATOMIC, true);
383 if (!skb_copy) 383 if (!skb_copy)
384 continue; 384 continue;
385 385
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 671f9817b4f4..26631679a1fa 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -653,7 +653,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
653 tipc_bearer_send(b->identity, buf, &b->bcast_addr); 653 tipc_bearer_send(b->identity, buf, &b->bcast_addr);
654 } else { 654 } else {
655 /* Avoid concurrent buffer access */ 655 /* Avoid concurrent buffer access */
656 tbuf = pskb_copy(buf, GFP_ATOMIC); 656 tbuf = pskb_copy_for_clone(buf, GFP_ATOMIC);
657 if (!tbuf) 657 if (!tbuf)
658 break; 658 break;
659 tipc_bearer_send(b->identity, tbuf, &b->bcast_addr); 659 tipc_bearer_send(b->identity, tbuf, &b->bcast_addr);