diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d898b32dedccccbd4bda3e79ae787018fc2fbb28..bba1330757c025fc783cf10c2d6e0cfd349f2f5c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -492,7 +492,6 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1, * @napi_id: id of the NAPI struct this skb came from * @secmark: security marking * @mark: Generic packet mark - * @dropcount: total number of sk_receive_queue overflows * @vlan_proto: vlan encapsulation protocol * @vlan_tci: vlan tag control information * @inner_protocol: Protocol (encapsulation) @@ -641,7 +640,6 @@ struct sk_buff { #endif union { __u32 mark; - __u32 dropcount; __u32 reserved_tailroom; }; diff --git a/include/net/sock.h b/include/net/sock.h index 0996fe451e5f92cd4312c77317e530ccb0af80b8..38369d3580a140dd7c652b07031f91661d0a6703 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2078,13 +2078,27 @@ static inline int sock_intr_errno(long timeo) return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR; } +struct sock_skb_cb { + u32 dropcount; +}; + +/* Store sock_skb_cb at the end of skb->cb[] so protocol families + * using skb->cb[] would keep using it directly and utilize its + * alignement guarantee. + */ +#define SOCK_SKB_CB_OFFSET ((FIELD_SIZEOF(struct sk_buff, cb) - \ + sizeof(struct sock_skb_cb))) + +#define SOCK_SKB_CB(__skb) ((struct sock_skb_cb *)((__skb)->cb + \ + SOCK_SKB_CB_OFFSET)) + #define sock_skb_cb_check_size(size) \ - BUILD_BUG_ON((size) > FIELD_SIZEOF(struct sk_buff, cb)) + BUILD_BUG_ON((size) > SOCK_SKB_CB_OFFSET) static inline void sock_skb_set_dropcount(const struct sock *sk, struct sk_buff *skb) { - skb->dropcount = atomic_read(&sk->sk_drops); + SOCK_SKB_CB(skb)->dropcount = atomic_read(&sk->sk_drops); } void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, diff --git a/net/socket.c b/net/socket.c index bbedbfcb42c2505fceb57fa058f262d90e1670ed..b78cf601a021c4dd4c9d91a872a2f512b92b7977 100644 --- a/net/socket.c +++ b/net/socket.c @@ -731,9 +731,9 @@ EXPORT_SYMBOL_GPL(__sock_recv_wifi_status); static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { - if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount) + if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount) put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL, - sizeof(__u32), &skb->dropcount); + sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount); } void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,