Commit d629be85 authored by Stefano Brivio's avatar Stefano Brivio Committed by Greg Kroah-Hartman

net: Don't copy pfmemalloc flag in __copy_skb_header()

[ Upstream commit 8b700862 ]

The pfmemalloc flag indicates that the skb was allocated from
the PFMEMALLOC reserves, and the flag is currently copied on skb
copy and clone.

However, an skb copied from an skb flagged with pfmemalloc
wasn't necessarily allocated from PFMEMALLOC reserves, and on
the other hand an skb allocated that way might be copied from an
skb that wasn't.

So we should not copy the flag on skb copy, and rather decide
whether to allow an skb to be associated with sockets unrelated
to page reclaim depending only on how it was allocated.

Move the pfmemalloc flag before headers_start[0] using an
existing 1-bit hole, so that __copy_skb_header() doesn't copy
it.

When cloning, we'll now take care of this flag explicitly,
contravening to the warning comment of __skb_clone().

While at it, restore the newline usage introduced by commit
b1937227 ("net: reorganize sk_buff for faster
__copy_skb_header()") to visually separate bytes used in
bitfields after headers_start[0], that was gone after commit
a9e419dc ("netfilter: merge ctinfo into nfct pointer storage
area"), and describe the pfmemalloc flag in the kernel-doc
structure comment.

This doesn't change the size of sk_buff or cacheline boundaries,
but consolidates the 15 bits hole before tc_index into a 2 bytes
hole before csum, that could now be filled more easily.
Reported-by: default avatarPatrick Talbert <ptalbert@redhat.com>
Fixes: c93bdd0e ("netvm: allow skb allocation to use PFMEMALLOC reserves")
Signed-off-by: default avatarStefano Brivio <sbrivio@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8a82aee2
...@@ -514,6 +514,7 @@ static inline bool skb_mstamp_after(const struct skb_mstamp *t1, ...@@ -514,6 +514,7 @@ static inline bool skb_mstamp_after(const struct skb_mstamp *t1,
* @hash: the packet hash * @hash: the packet hash
* @queue_mapping: Queue mapping for multiqueue devices * @queue_mapping: Queue mapping for multiqueue devices
* @xmit_more: More SKBs are pending for this queue * @xmit_more: More SKBs are pending for this queue
* @pfmemalloc: skbuff was allocated from PFMEMALLOC reserves
* @ndisc_nodetype: router type (from link layer) * @ndisc_nodetype: router type (from link layer)
* @ooo_okay: allow the mapping of a socket to a queue to be changed * @ooo_okay: allow the mapping of a socket to a queue to be changed
* @l4_hash: indicate hash is a canonical 4-tuple hash over transport * @l4_hash: indicate hash is a canonical 4-tuple hash over transport
...@@ -594,8 +595,8 @@ struct sk_buff { ...@@ -594,8 +595,8 @@ struct sk_buff {
fclone:2, fclone:2,
peeked:1, peeked:1,
head_frag:1, head_frag:1,
xmit_more:1; xmit_more:1,
/* one bit hole */ pfmemalloc:1;
kmemcheck_bitfield_end(flags1); kmemcheck_bitfield_end(flags1);
/* fields enclosed in headers_start/headers_end are copied /* fields enclosed in headers_start/headers_end are copied
...@@ -615,19 +616,18 @@ struct sk_buff { ...@@ -615,19 +616,18 @@ struct sk_buff {
__u8 __pkt_type_offset[0]; __u8 __pkt_type_offset[0];
__u8 pkt_type:3; __u8 pkt_type:3;
__u8 pfmemalloc:1;
__u8 ignore_df:1; __u8 ignore_df:1;
__u8 nfctinfo:3; __u8 nfctinfo:3;
__u8 nf_trace:1; __u8 nf_trace:1;
__u8 ip_summed:2; __u8 ip_summed:2;
__u8 ooo_okay:1; __u8 ooo_okay:1;
__u8 l4_hash:1; __u8 l4_hash:1;
__u8 sw_hash:1; __u8 sw_hash:1;
__u8 wifi_acked_valid:1; __u8 wifi_acked_valid:1;
__u8 wifi_acked:1; __u8 wifi_acked:1;
__u8 no_fcs:1; __u8 no_fcs:1;
/* Indicates the inner headers are valid in the skbuff. */ /* Indicates the inner headers are valid in the skbuff. */
__u8 encapsulation:1; __u8 encapsulation:1;
__u8 encap_hdr_csum:1; __u8 encap_hdr_csum:1;
...@@ -635,11 +635,11 @@ struct sk_buff { ...@@ -635,11 +635,11 @@ struct sk_buff {
__u8 csum_complete_sw:1; __u8 csum_complete_sw:1;
__u8 csum_level:2; __u8 csum_level:2;
__u8 csum_bad:1; __u8 csum_bad:1;
#ifdef CONFIG_IPV6_NDISC_NODETYPE #ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2; __u8 ndisc_nodetype:2;
#endif #endif
__u8 ipvs_property:1; __u8 ipvs_property:1;
__u8 inner_protocol_type:1; __u8 inner_protocol_type:1;
__u8 remcsum_offload:1; __u8 remcsum_offload:1;
/* 3 or 5 bit hole */ /* 3 or 5 bit hole */
......
...@@ -828,6 +828,8 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) ...@@ -828,6 +828,8 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
n->cloned = 1; n->cloned = 1;
n->nohdr = 0; n->nohdr = 0;
n->peeked = 0; n->peeked = 0;
if (skb->pfmemalloc)
n->pfmemalloc = 1;
n->destructor = NULL; n->destructor = NULL;
C(tail); C(tail);
C(end); C(end);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment