| From aba27224697962e2556da8e7d936b025be757954 Mon Sep 17 00:00:00 2001 |
| From: Jakub Kicinski <jakub.kicinski@netronome.com> |
| Date: Sun, 6 Oct 2019 21:09:27 -0700 |
| Subject: [PATCH] net: sockmap: use bitmap for copy info |
| |
| commit 163ab96b52ae2bb2d8f188cd29f0b570610f9007 upstream. |
| |
| Don't use bool array in struct sk_msg_sg, save 12 bytes. |
| |
| Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> |
| Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h |
| index 4afabf2d2a42..b19684869145 100644 |
| --- a/include/linux/skmsg.h |
| +++ b/include/linux/skmsg.h |
| @@ -28,13 +28,14 @@ struct sk_msg_sg { |
| u32 end; |
| u32 size; |
| u32 copybreak; |
| - bool copy[MAX_MSG_FRAGS]; |
| + unsigned long copy; |
| /* The extra element is used for chaining the front and sections when |
| * the list becomes partitioned (e.g. end < start). The crypto APIs |
| * require the chaining. |
| */ |
| struct scatterlist data[MAX_MSG_FRAGS + 1]; |
| }; |
| +static_assert(BITS_PER_LONG >= MAX_MSG_FRAGS); |
| |
| /* UAPI in filter.c depends on struct sk_msg_sg being first element. */ |
| struct sk_msg { |
| @@ -230,7 +231,7 @@ static inline void sk_msg_compute_data_pointers(struct sk_msg *msg) |
| { |
| struct scatterlist *sge = sk_msg_elem(msg, msg->sg.start); |
| |
| - if (msg->sg.copy[msg->sg.start]) { |
| + if (test_bit(msg->sg.start, &msg->sg.copy)) { |
| msg->data = NULL; |
| msg->data_end = NULL; |
| } else { |
| @@ -249,7 +250,7 @@ static inline void sk_msg_page_add(struct sk_msg *msg, struct page *page, |
| sg_set_page(sge, page, len, offset); |
| sg_unmark_end(sge); |
| |
| - msg->sg.copy[msg->sg.end] = true; |
| + __set_bit(msg->sg.end, &msg->sg.copy); |
| msg->sg.size += len; |
| sk_msg_iter_next(msg, end); |
| } |
| @@ -257,7 +258,10 @@ static inline void sk_msg_page_add(struct sk_msg *msg, struct page *page, |
| static inline void sk_msg_sg_copy(struct sk_msg *msg, u32 i, bool copy_state) |
| { |
| do { |
| - msg->sg.copy[i] = copy_state; |
| + if (copy_state) |
| + __set_bit(i, &msg->sg.copy); |
| + else |
| + __clear_bit(i, &msg->sg.copy); |
| sk_msg_iter_var_next(i); |
| if (i == msg->sg.end) |
| break; |
| diff --git a/net/core/filter.c b/net/core/filter.c |
| index 7aee6f368754..d26bfec9c91d 100644 |
| --- a/net/core/filter.c |
| +++ b/net/core/filter.c |
| @@ -2244,7 +2244,7 @@ BPF_CALL_4(bpf_msg_pull_data, struct sk_msg *, msg, u32, start, |
| * account for the headroom. |
| */ |
| bytes_sg_total = start - offset + bytes; |
| - if (!msg->sg.copy[i] && bytes_sg_total <= len) |
| + if (!test_bit(i, &msg->sg.copy) && bytes_sg_total <= len) |
| goto out; |
| |
| /* At this point we need to linearize multiple scatterlist |
| @@ -2449,7 +2449,7 @@ BPF_CALL_4(bpf_msg_push_data, struct sk_msg *, msg, u32, start, |
| /* Place newly allocated data buffer */ |
| sk_mem_charge(msg->sk, len); |
| msg->sg.size += len; |
| - msg->sg.copy[new] = false; |
| + __clear_bit(new, &msg->sg.copy); |
| sg_set_page(&msg->sg.data[new], page, len + copy, 0); |
| if (rsge.length) { |
| get_page(sg_page(&rsge)); |
| -- |
| 2.7.4 |
| |