netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] net: add skb allocation flags to __pskb_copy
@ 2014-06-07 22:19 Octavian Purdila
  2014-06-11  7:41 ` David Miller
  0 siblings, 1 reply; 4+ messages in thread
From: Octavian Purdila @ 2014-06-07 22:19 UTC (permalink / raw)
  To: netdev; +Cc: christoph.paasch, Octavian Purdila

There are several instances where a __pskb_copy is immediately
followed by an skb_clone. Add a new parameter to __pskb_copy to allow
the skb to be allocated from the fclone cache and thus speed up
subsequent skb_clone calls.

Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
---
 include/linux/skbuff.h   | 6 +++---
 net/bluetooth/hci_sock.c | 5 +++--
 net/core/skbuff.c        | 7 +++++--
 net/ipv4/tcp_output.c    | 2 +-
 net/nfc/llcp_core.c      | 2 +-
 net/nfc/rawsock.c        | 2 +-
 6 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index c705808..7c5b56a 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -744,8 +744,8 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
 int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask);
 struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t priority);
 struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t priority);
-struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask);
-
+struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask,
+			    int flags);
 int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, gfp_t gfp_mask);
 struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
 				     unsigned int headroom);
@@ -2235,7 +2235,7 @@ static inline dma_addr_t skb_frag_dma_map(struct device *dev,
 static inline struct sk_buff *pskb_copy(struct sk_buff *skb,
 					gfp_t gfp_mask)
 {
-	return __pskb_copy(skb, skb_headroom(skb), gfp_mask);
+	return __pskb_copy(skb, skb_headroom(skb), gfp_mask, 0);
 }
 
 /**
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index f608bff..c2f5db3 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -143,7 +143,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
 
 		if (!skb_copy) {
 			/* Create a private copy with headroom */
-			skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
+			skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC,
+					       SKB_ALLOC_FCLONE);
 			if (!skb_copy)
 				continue;
 
@@ -248,7 +249,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
 
 			/* Create a private copy with headroom */
 			skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE,
-					       GFP_ATOMIC);
+					       GFP_ATOMIC, SKB_ALLOC_FCLONE);
 			if (!skb_copy)
 				continue;
 
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 05f4bef..03863be 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -955,6 +955,7 @@ EXPORT_SYMBOL(skb_copy);
  *	@skb: buffer to copy
  *	@headroom: headroom of new skb
  *	@gfp_mask: allocation priority
+ *	@flags: skb allocation flags (e.g. SKB_ALLOC_FCLONE)
  *
  *	Make a copy of both an &sk_buff and part of its data, located
  *	in header. Fragmented data remain shared. This is used when
@@ -964,11 +965,13 @@ EXPORT_SYMBOL(skb_copy);
  *	The returned buffer has a reference count of 1.
  */
 
-struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
+struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask,
+			    int flags)
 {
 	unsigned int size = skb_headlen(skb) + headroom;
 	struct sk_buff *n = __alloc_skb(size, gfp_mask,
-					skb_alloc_rx_flag(skb), NUMA_NO_NODE);
+					flags | skb_alloc_rx_flag(skb),
+					NUMA_NO_NODE);
 
 	if (!n)
 		goto out;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index d463c35..17fe18d 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2490,7 +2490,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
 	if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) ||
 		     skb_headroom(skb) >= 0xFFFF)) {
 		struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
-						   GFP_ATOMIC);
+						   GFP_ATOMIC, 0);
 		err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
 			     -ENOBUFS;
 	} else {
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index f6278da..df960a3 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -681,7 +681,7 @@ void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
 
 		if (skb_copy == NULL) {
 			skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE,
-					       GFP_ATOMIC);
+					       GFP_ATOMIC, SKB_ALLOC_FCLONE);
 
 			if (skb_copy == NULL)
 				continue;
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index 55eefee..e8c1805 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -379,7 +379,7 @@ void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb,
 	sk_for_each(sk, &raw_sk_list.head) {
 		if (!skb_copy) {
 			skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE,
-				     GFP_ATOMIC);
+					       GFP_ATOMIC, SKB_ALLOC_FCLONE);
 			if (!skb_copy)
 				continue;
 
-- 
1.8.3.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] net: add skb allocation flags to __pskb_copy
       [not found] <b75b291eb5364f13904268302d789357@UCL-MBX03.OASIS.UCLOUVAIN.BE>
@ 2014-06-08 15:59 ` Christoph Paasch
  2014-06-08 16:49   ` Octavian Purdila
  0 siblings, 1 reply; 4+ messages in thread
From: Christoph Paasch @ 2014-06-08 15:59 UTC (permalink / raw)
  To: Octavian Purdila; +Cc: netdev@vger.kernel.org

Hello Octavian,

On 07/06/14 - 22:19:29, Octavian Purdila wrote:
> There are several instances where a __pskb_copy is immediately
> followed by an skb_clone. Add a new parameter to __pskb_copy to allow
> the skb to be allocated from the fclone cache and thus speed up
> subsequent skb_clone calls.
> 
> Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
> ---
>  include/linux/skbuff.h   | 6 +++---
>  net/bluetooth/hci_sock.c | 5 +++--
>  net/core/skbuff.c        | 7 +++++--
>  net/ipv4/tcp_output.c    | 2 +-
>  net/nfc/llcp_core.c      | 2 +-
>  net/nfc/rawsock.c        | 2 +-
>  6 files changed, 14 insertions(+), 10 deletions(-)

I found two more cases where the stack could benefit from using an FCLONE:

* batadv_nc_skb_store_before_coding() does a pskb_copy and later in
  batadv_nc_skb_store_for_decoding() the skb_clone is done.

* tipc_bcbearer_send() also does a pskb_copy, and the send_msg-callback (in
  tipc_bearer_send()) does a clone too later on in tipc_l2_send_msg().


Cheers,
Christoph

> 
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index c705808..7c5b56a 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -744,8 +744,8 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
>  int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask);
>  struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t priority);
>  struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t priority);
> -struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask);
> -
> +struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask,
> +			    int flags);
>  int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, gfp_t gfp_mask);
>  struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
>  				     unsigned int headroom);
> @@ -2235,7 +2235,7 @@ static inline dma_addr_t skb_frag_dma_map(struct device *dev,
>  static inline struct sk_buff *pskb_copy(struct sk_buff *skb,
>  					gfp_t gfp_mask)
>  {
> -	return __pskb_copy(skb, skb_headroom(skb), gfp_mask);
> +	return __pskb_copy(skb, skb_headroom(skb), gfp_mask, 0);
>  }
>  
>  /**
> diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
> index f608bff..c2f5db3 100644
> --- a/net/bluetooth/hci_sock.c
> +++ b/net/bluetooth/hci_sock.c
> @@ -143,7 +143,8 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
>  
>  		if (!skb_copy) {
>  			/* Create a private copy with headroom */
> -			skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC);
> +			skb_copy = __pskb_copy(skb, 1, GFP_ATOMIC,
> +					       SKB_ALLOC_FCLONE);
>  			if (!skb_copy)
>  				continue;
>  
> @@ -248,7 +249,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
>  
>  			/* Create a private copy with headroom */
>  			skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE,
> -					       GFP_ATOMIC);
> +					       GFP_ATOMIC, SKB_ALLOC_FCLONE);
>  			if (!skb_copy)
>  				continue;
>  
> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
> index 05f4bef..03863be 100644
> --- a/net/core/skbuff.c
> +++ b/net/core/skbuff.c
> @@ -955,6 +955,7 @@ EXPORT_SYMBOL(skb_copy);
>   *	@skb: buffer to copy
>   *	@headroom: headroom of new skb
>   *	@gfp_mask: allocation priority
> + *	@flags: skb allocation flags (e.g. SKB_ALLOC_FCLONE)
>   *
>   *	Make a copy of both an &sk_buff and part of its data, located
>   *	in header. Fragmented data remain shared. This is used when
> @@ -964,11 +965,13 @@ EXPORT_SYMBOL(skb_copy);
>   *	The returned buffer has a reference count of 1.
>   */
>  
> -struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
> +struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask,
> +			    int flags)
>  {
>  	unsigned int size = skb_headlen(skb) + headroom;
>  	struct sk_buff *n = __alloc_skb(size, gfp_mask,
> -					skb_alloc_rx_flag(skb), NUMA_NO_NODE);
> +					flags | skb_alloc_rx_flag(skb),
> +					NUMA_NO_NODE);
>  
>  	if (!n)
>  		goto out;
> diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
> index d463c35..17fe18d 100644
> --- a/net/ipv4/tcp_output.c
> +++ b/net/ipv4/tcp_output.c
> @@ -2490,7 +2490,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
>  	if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) ||
>  		     skb_headroom(skb) >= 0xFFFF)) {
>  		struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
> -						   GFP_ATOMIC);
> +						   GFP_ATOMIC, 0);
>  		err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
>  			     -ENOBUFS;
>  	} else {
> diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
> index f6278da..df960a3 100644
> --- a/net/nfc/llcp_core.c
> +++ b/net/nfc/llcp_core.c
> @@ -681,7 +681,7 @@ void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
>  
>  		if (skb_copy == NULL) {
>  			skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE,
> -					       GFP_ATOMIC);
> +					       GFP_ATOMIC, SKB_ALLOC_FCLONE);
>  
>  			if (skb_copy == NULL)
>  				continue;
> diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
> index 55eefee..e8c1805 100644
> --- a/net/nfc/rawsock.c
> +++ b/net/nfc/rawsock.c
> @@ -379,7 +379,7 @@ void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb,
>  	sk_for_each(sk, &raw_sk_list.head) {
>  		if (!skb_copy) {
>  			skb_copy = __pskb_copy(skb, NFC_RAW_HEADER_SIZE,
> -				     GFP_ATOMIC);
> +					       GFP_ATOMIC, SKB_ALLOC_FCLONE);
>  			if (!skb_copy)
>  				continue;
>  
> -- 
> 1.8.3.2
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] net: add skb allocation flags to __pskb_copy
  2014-06-08 15:59 ` Christoph Paasch
@ 2014-06-08 16:49   ` Octavian Purdila
  0 siblings, 0 replies; 4+ messages in thread
From: Octavian Purdila @ 2014-06-08 16:49 UTC (permalink / raw)
  To: Christoph Paasch; +Cc: netdev@vger.kernel.org

GOn Sun, Jun 8, 2014 at 6:59 PM, Christoph Paasch
<christoph.paasch@uclouvain.be> wrote:
> Hello Octavian,
>
> On 07/06/14 - 22:19:29, Octavian Purdila wrote:
>> There are several instances where a __pskb_copy is immediately
>> followed by an skb_clone. Add a new parameter to __pskb_copy to allow
>> the skb to be allocated from the fclone cache and thus speed up
>> subsequent skb_clone calls.
>>
>> Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
>> ---
>>  include/linux/skbuff.h   | 6 +++---
>>  net/bluetooth/hci_sock.c | 5 +++--
>>  net/core/skbuff.c        | 7 +++++--
>>  net/ipv4/tcp_output.c    | 2 +-
>>  net/nfc/llcp_core.c      | 2 +-
>>  net/nfc/rawsock.c        | 2 +-
>>  6 files changed, 14 insertions(+), 10 deletions(-)
>
> I found two more cases where the stack could benefit from using an FCLONE:
>
> * batadv_nc_skb_store_before_coding() does a pskb_copy and later in
>   batadv_nc_skb_store_for_decoding() the skb_clone is done.
>
> * tipc_bcbearer_send() also does a pskb_copy, and the send_msg-callback (in
>   tipc_bearer_send()) does a clone too later on in tipc_l2_send_msg().
>

Missed those, I will send a new patch which adds a new parameter to
psbk_copy as well then.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] net: add skb allocation flags to __pskb_copy
  2014-06-07 22:19 [PATCH net-next] net: add skb allocation flags to __pskb_copy Octavian Purdila
@ 2014-06-11  7:41 ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2014-06-11  7:41 UTC (permalink / raw)
  To: octavian.purdila; +Cc: netdev, christoph.paasch

From: Octavian Purdila <octavian.purdila@intel.com>
Date: Sun,  8 Jun 2014 01:19:29 +0300

> There are several instances where a __pskb_copy is immediately
> followed by an skb_clone. Add a new parameter to __pskb_copy to allow
> the skb to be allocated from the fclone cache and thus speed up
> subsequent skb_clone calls.
> 
> Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>

These SKB_ALLOC_* values are really internal, let's not use them explicitly
outside of skbuff.h and skbuff.c

Change this interface to instead take a boolean, which when true will
cause and fclone allocation.

Thank you.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-06-11  7:41 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-07 22:19 [PATCH net-next] net: add skb allocation flags to __pskb_copy Octavian Purdila
2014-06-11  7:41 ` David Miller
     [not found] <b75b291eb5364f13904268302d789357@UCL-MBX03.OASIS.UCLOUVAIN.BE>
2014-06-08 15:59 ` Christoph Paasch
2014-06-08 16:49   ` Octavian Purdila

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).