* [RFC PATCH v1 13/57] bpf: Remove PAGE_SIZE compile-time constant assumption
[not found] ` <20241014105912.3207374-1-ryan.roberts@arm.com>
@ 2024-10-14 10:58 ` Ryan Roberts
2024-10-16 14:38 ` Ryan Roberts
2024-10-14 10:58 ` [RFC PATCH v1 29/57] net: igb: " Ryan Roberts
1 sibling, 1 reply; 4+ messages in thread
From: Ryan Roberts @ 2024-10-14 10:58 UTC (permalink / raw)
To: Alexei Starovoitov, Andrew Morton, Anshuman Khandual,
Ard Biesheuvel, Catalin Marinas, Daniel Borkmann,
David Hildenbrand, Greg Marsden, Ivan Ivanov, Kalesh Singh,
Marc Zyngier, Mark Rutland, Matthias Brugger, Miroslav Benes,
Will Deacon
Cc: Ryan Roberts, bpf, linux-arm-kernel, linux-kernel, linux-mm
To prepare for supporting boot-time page size selection, refactor code
to remove assumptions about PAGE_SIZE being compile-time constant. Code
intended to be equivalent when compile-time page size is active.
Refactor "struct bpf_ringbuf" so that consumer_pos, producer_pos,
pending_pos and data are no longer embedded at (static) page offsets
within the struct. This can't work for boot-time page size because the
page size isn't known at compile-time. Instead, only define the meta
data in the struct, along with pointers to those values. At "struct
bpf_ringbuf" allocation time, the extra pages are allocated at the end
and the pointers are initialized to point to the correct locations.
Additionally, only expose the __PAGE_SIZE enum to BTF for compile-time
page size builds. We don't know the page size at compile-time for
boot-time builds. NOTE: This may need some extra thought; perhaps
__PAGE_SIZE should be exposed as 0 in this case? And/or perhaps
__PAGE_SIZE_MIN/__PAGE_SIZE_MAX should be exposed? And there would need
to be a runtime mechanism for querying the page size (e.g.
getpagesize()).
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
***NOTE***
Any confused maintainers may want to read the cover note here for context:
https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/
kernel/bpf/core.c | 9 ++++++--
kernel/bpf/ringbuf.c | 54 ++++++++++++++++++++++++--------------------
2 files changed, 37 insertions(+), 26 deletions(-)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 7ee62e38faf0e..485875aa78e63 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -89,10 +89,15 @@ void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, uns
return NULL;
}
-/* tell bpf programs that include vmlinux.h kernel's PAGE_SIZE */
+/*
+ * tell bpf programs that include vmlinux.h kernel's PAGE_SIZE. We can only do
+ * this for compile-time PAGE_SIZE builds.
+ */
+#if PAGE_SIZE_MIN == PAGE_SIZE_MAX
enum page_size_enum {
__PAGE_SIZE = PAGE_SIZE
};
+#endif
struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flags)
{
@@ -100,7 +105,7 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
struct bpf_prog_aux *aux;
struct bpf_prog *fp;
- size = round_up(size, __PAGE_SIZE);
+ size = round_up(size, PAGE_SIZE);
fp = __vmalloc(size, gfp_flags);
if (fp == NULL)
return NULL;
diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
index e20b90c361316..8e4093ddbc638 100644
--- a/kernel/bpf/ringbuf.c
+++ b/kernel/bpf/ringbuf.c
@@ -14,9 +14,9 @@
#define RINGBUF_CREATE_FLAG_MASK (BPF_F_NUMA_NODE)
-/* non-mmap()'able part of bpf_ringbuf (everything up to consumer page) */
+/* non-mmap()'able part of bpf_ringbuf (everything defined in struct) */
#define RINGBUF_PGOFF \
- (offsetof(struct bpf_ringbuf, consumer_pos) >> PAGE_SHIFT)
+ (PAGE_ALIGN(sizeof(struct bpf_ringbuf)) >> PAGE_SHIFT)
/* consumer page and producer page */
#define RINGBUF_POS_PAGES 2
#define RINGBUF_NR_META_PAGES (RINGBUF_PGOFF + RINGBUF_POS_PAGES)
@@ -69,10 +69,10 @@ struct bpf_ringbuf {
* validate each sample to ensure that they're correctly formatted, and
* fully contained within the ring buffer.
*/
- unsigned long consumer_pos __aligned(PAGE_SIZE);
- unsigned long producer_pos __aligned(PAGE_SIZE);
- unsigned long pending_pos;
- char data[] __aligned(PAGE_SIZE);
+ unsigned long *consumer_pos;
+ unsigned long *producer_pos;
+ unsigned long *pending_pos;
+ char *data;
};
struct bpf_ringbuf_map {
@@ -134,9 +134,15 @@ static struct bpf_ringbuf *bpf_ringbuf_area_alloc(size_t data_sz, int numa_node)
rb = vmap(pages, nr_meta_pages + 2 * nr_data_pages,
VM_MAP | VM_USERMAP, PAGE_KERNEL);
if (rb) {
+ void *base = rb;
+
kmemleak_not_leak(pages);
rb->pages = pages;
rb->nr_pages = nr_pages;
+ rb->consumer_pos = (unsigned long *)(base + PAGE_SIZE * RINGBUF_PGOFF);
+ rb->producer_pos = (unsigned long *)(base + PAGE_SIZE * (RINGBUF_PGOFF + 1));
+ rb->pending_pos = rb->producer_pos + 1;
+ rb->data = base + PAGE_SIZE * nr_meta_pages;
return rb;
}
@@ -179,9 +185,9 @@ static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node)
init_irq_work(&rb->work, bpf_ringbuf_notify);
rb->mask = data_sz - 1;
- rb->consumer_pos = 0;
- rb->producer_pos = 0;
- rb->pending_pos = 0;
+ *rb->consumer_pos = 0;
+ *rb->producer_pos = 0;
+ *rb->pending_pos = 0;
return rb;
}
@@ -300,8 +306,8 @@ static unsigned long ringbuf_avail_data_sz(struct bpf_ringbuf *rb)
{
unsigned long cons_pos, prod_pos;
- cons_pos = smp_load_acquire(&rb->consumer_pos);
- prod_pos = smp_load_acquire(&rb->producer_pos);
+ cons_pos = smp_load_acquire(rb->consumer_pos);
+ prod_pos = smp_load_acquire(rb->producer_pos);
return prod_pos - cons_pos;
}
@@ -418,7 +424,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
if (len > ringbuf_total_data_sz(rb))
return NULL;
- cons_pos = smp_load_acquire(&rb->consumer_pos);
+ cons_pos = smp_load_acquire(rb->consumer_pos);
if (in_nmi()) {
if (!spin_trylock_irqsave(&rb->spinlock, flags))
@@ -427,8 +433,8 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
spin_lock_irqsave(&rb->spinlock, flags);
}
- pend_pos = rb->pending_pos;
- prod_pos = rb->producer_pos;
+ pend_pos = *rb->pending_pos;
+ prod_pos = *rb->producer_pos;
new_prod_pos = prod_pos + len;
while (pend_pos < prod_pos) {
@@ -440,7 +446,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
tmp_size = round_up(tmp_size + BPF_RINGBUF_HDR_SZ, 8);
pend_pos += tmp_size;
}
- rb->pending_pos = pend_pos;
+ *rb->pending_pos = pend_pos;
/* check for out of ringbuf space:
* - by ensuring producer position doesn't advance more than
@@ -460,7 +466,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
hdr->pg_off = pg_off;
/* pairs with consumer's smp_load_acquire() */
- smp_store_release(&rb->producer_pos, new_prod_pos);
+ smp_store_release(rb->producer_pos, new_prod_pos);
spin_unlock_irqrestore(&rb->spinlock, flags);
@@ -506,7 +512,7 @@ static void bpf_ringbuf_commit(void *sample, u64 flags, bool discard)
* new data availability
*/
rec_pos = (void *)hdr - (void *)rb->data;
- cons_pos = smp_load_acquire(&rb->consumer_pos) & rb->mask;
+ cons_pos = smp_load_acquire(rb->consumer_pos) & rb->mask;
if (flags & BPF_RB_FORCE_WAKEUP)
irq_work_queue(&rb->work);
@@ -580,9 +586,9 @@ BPF_CALL_2(bpf_ringbuf_query, struct bpf_map *, map, u64, flags)
case BPF_RB_RING_SIZE:
return ringbuf_total_data_sz(rb);
case BPF_RB_CONS_POS:
- return smp_load_acquire(&rb->consumer_pos);
+ return smp_load_acquire(rb->consumer_pos);
case BPF_RB_PROD_POS:
- return smp_load_acquire(&rb->producer_pos);
+ return smp_load_acquire(rb->producer_pos);
default:
return 0;
}
@@ -680,12 +686,12 @@ static int __bpf_user_ringbuf_peek(struct bpf_ringbuf *rb, void **sample, u32 *s
u64 cons_pos, prod_pos;
/* Synchronizes with smp_store_release() in user-space producer. */
- prod_pos = smp_load_acquire(&rb->producer_pos);
+ prod_pos = smp_load_acquire(rb->producer_pos);
if (prod_pos % 8)
return -EINVAL;
/* Synchronizes with smp_store_release() in __bpf_user_ringbuf_sample_release() */
- cons_pos = smp_load_acquire(&rb->consumer_pos);
+ cons_pos = smp_load_acquire(rb->consumer_pos);
if (cons_pos >= prod_pos)
return -ENODATA;
@@ -715,7 +721,7 @@ static int __bpf_user_ringbuf_peek(struct bpf_ringbuf *rb, void **sample, u32 *s
* Update the consumer pos, and return -EAGAIN so the caller
* knows to skip this sample and try to read the next one.
*/
- smp_store_release(&rb->consumer_pos, cons_pos + total_len);
+ smp_store_release(rb->consumer_pos, cons_pos + total_len);
return -EAGAIN;
}
@@ -737,9 +743,9 @@ static void __bpf_user_ringbuf_sample_release(struct bpf_ringbuf *rb, size_t siz
* prevents another task from writing to consumer_pos after it was read
* by this task with smp_load_acquire() in __bpf_user_ringbuf_peek().
*/
- consumer_pos = rb->consumer_pos;
+ consumer_pos = *rb->consumer_pos;
/* Synchronizes with smp_load_acquire() in user-space producer. */
- smp_store_release(&rb->consumer_pos, consumer_pos + rounded_size);
+ smp_store_release(rb->consumer_pos, consumer_pos + rounded_size);
}
BPF_CALL_4(bpf_user_ringbuf_drain, struct bpf_map *, map,
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [RFC PATCH v1 29/57] net: igb: Remove PAGE_SIZE compile-time constant assumption
[not found] ` <20241014105912.3207374-1-ryan.roberts@arm.com>
2024-10-14 10:58 ` [RFC PATCH v1 13/57] bpf: Remove PAGE_SIZE compile-time constant assumption Ryan Roberts
@ 2024-10-14 10:58 ` Ryan Roberts
2024-10-16 14:45 ` Ryan Roberts
1 sibling, 1 reply; 4+ messages in thread
From: Ryan Roberts @ 2024-10-14 10:58 UTC (permalink / raw)
To: David S. Miller, Andrew Morton, Anshuman Khandual, Ard Biesheuvel,
Catalin Marinas, David Hildenbrand, Eric Dumazet, Greg Marsden,
Ivan Ivanov, Jakub Kicinski, Kalesh Singh, Marc Zyngier,
Mark Rutland, Matthias Brugger, Miroslav Benes, Paolo Abeni,
Will Deacon
Cc: Ryan Roberts, bpf, intel-wired-lan, linux-arm-kernel,
linux-kernel, linux-mm, netdev
To prepare for supporting boot-time page size selection, refactor code
to remove assumptions about PAGE_SIZE being compile-time constant. Code
intended to be equivalent when compile-time page size is active.
Convert CPP conditionals to C conditionals. The compiler will dead code
strip when doing a compile-time page size build, for the same end
effect. But this will also work with boot-time page size builds.
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
---
***NOTE***
Any confused maintainers may want to read the cover note here for context:
https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/
drivers/net/ethernet/intel/igb/igb.h | 25 ++--
drivers/net/ethernet/intel/igb/igb_main.c | 149 +++++++++++-----------
2 files changed, 82 insertions(+), 92 deletions(-)
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 3c2dc7bdebb50..04aeebcd363b3 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -158,7 +158,6 @@ struct vf_mac_filter {
* up negative. In these cases we should fall back to the 3K
* buffers.
*/
-#if (PAGE_SIZE < 8192)
#define IGB_MAX_FRAME_BUILD_SKB (IGB_RXBUFFER_1536 - NET_IP_ALIGN)
#define IGB_2K_TOO_SMALL_WITH_PADDING \
((NET_SKB_PAD + IGB_TS_HDR_LEN + IGB_RXBUFFER_1536) > SKB_WITH_OVERHEAD(IGB_RXBUFFER_2048))
@@ -177,6 +176,9 @@ static inline int igb_skb_pad(void)
{
int rx_buf_len;
+ if (PAGE_SIZE >= 8192)
+ return NET_SKB_PAD + NET_IP_ALIGN;
+
/* If a 2K buffer cannot handle a standard Ethernet frame then
* optimize padding for a 3K buffer instead of a 1.5K buffer.
*
@@ -196,9 +198,6 @@ static inline int igb_skb_pad(void)
}
#define IGB_SKB_PAD igb_skb_pad()
-#else
-#define IGB_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
-#endif
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
@@ -280,7 +279,7 @@ struct igb_tx_buffer {
struct igb_rx_buffer {
dma_addr_t dma;
struct page *page;
-#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
+#if (BITS_PER_LONG > 32) || (PAGE_SIZE_MAX >= 65536)
__u32 page_offset;
#else
__u16 page_offset;
@@ -403,22 +402,20 @@ enum e1000_ring_flags_t {
static inline unsigned int igb_rx_bufsz(struct igb_ring *ring)
{
-#if (PAGE_SIZE < 8192)
- if (ring_uses_large_buffer(ring))
- return IGB_RXBUFFER_3072;
+ if (PAGE_SIZE < 8192) {
+ if (ring_uses_large_buffer(ring))
+ return IGB_RXBUFFER_3072;
- if (ring_uses_build_skb(ring))
- return IGB_MAX_FRAME_BUILD_SKB;
-#endif
+ if (ring_uses_build_skb(ring))
+ return IGB_MAX_FRAME_BUILD_SKB;
+ }
return IGB_RXBUFFER_2048;
}
static inline unsigned int igb_rx_pg_order(struct igb_ring *ring)
{
-#if (PAGE_SIZE < 8192)
- if (ring_uses_large_buffer(ring))
+ if (PAGE_SIZE < 8192 && ring_uses_large_buffer(ring))
return 1;
-#endif
return 0;
}
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 1ef4cb871452a..4f2c53dece1a2 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -4797,9 +4797,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
struct igb_ring *rx_ring)
{
-#if (PAGE_SIZE < 8192)
struct e1000_hw *hw = &adapter->hw;
-#endif
/* set build_skb and buffer size flags */
clear_ring_build_skb_enabled(rx_ring);
@@ -4810,12 +4808,11 @@ static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
set_ring_build_skb_enabled(rx_ring);
-#if (PAGE_SIZE < 8192)
- if (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB ||
+ if (PAGE_SIZE < 8192 &&
+ (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB ||
IGB_2K_TOO_SMALL_WITH_PADDING ||
- rd32(E1000_RCTL) & E1000_RCTL_SBP)
+ rd32(E1000_RCTL) & E1000_RCTL_SBP))
set_ring_uses_large_buffer(rx_ring);
-#endif
}
/**
@@ -5314,12 +5311,10 @@ static void igb_set_rx_mode(struct net_device *netdev)
E1000_RCTL_VFE);
wr32(E1000_RCTL, rctl);
-#if (PAGE_SIZE < 8192)
- if (!adapter->vfs_allocated_count) {
+ if (PAGE_SIZE < 8192 && !adapter->vfs_allocated_count) {
if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
rlpml = IGB_MAX_FRAME_BUILD_SKB;
}
-#endif
wr32(E1000_RLPML, rlpml);
/* In order to support SR-IOV and eventually VMDq it is necessary to set
@@ -5338,11 +5333,10 @@ static void igb_set_rx_mode(struct net_device *netdev)
/* enable Rx jumbo frames, restrict as needed to support build_skb */
vmolr &= ~E1000_VMOLR_RLPML_MASK;
-#if (PAGE_SIZE < 8192)
- if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
+ if (PAGE_SIZE < 8192 &&
+ adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
vmolr |= IGB_MAX_FRAME_BUILD_SKB;
else
-#endif
vmolr |= MAX_JUMBO_FRAME_SIZE;
vmolr |= E1000_VMOLR_LPE;
@@ -8435,17 +8429,17 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
if (!dev_page_is_reusable(page))
return false;
-#if (PAGE_SIZE < 8192)
- /* if we are only owner of page we can reuse it */
- if (unlikely((rx_buf_pgcnt - pagecnt_bias) > 1))
- return false;
-#else
+ if (PAGE_SIZE < 8192) {
+ /* if we are only owner of page we can reuse it */
+ if (unlikely((rx_buf_pgcnt - pagecnt_bias) > 1))
+ return false;
+ } else {
#define IGB_LAST_OFFSET \
(SKB_WITH_OVERHEAD(PAGE_SIZE) - IGB_RXBUFFER_2048)
- if (rx_buffer->page_offset > IGB_LAST_OFFSET)
- return false;
-#endif
+ if (rx_buffer->page_offset > IGB_LAST_OFFSET)
+ return false;
+ }
/* If we have drained the page fragment pool we need to update
* the pagecnt_bias and page count so that we fully restock the
@@ -8473,20 +8467,22 @@ static void igb_add_rx_frag(struct igb_ring *rx_ring,
struct sk_buff *skb,
unsigned int size)
{
-#if (PAGE_SIZE < 8192)
- unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
-#else
- unsigned int truesize = ring_uses_build_skb(rx_ring) ?
+ unsigned int truesize;
+
+ if (PAGE_SIZE < 8192)
+ truesize = igb_rx_pg_size(rx_ring) / 2;
+ else
+ truesize = ring_uses_build_skb(rx_ring) ?
SKB_DATA_ALIGN(IGB_SKB_PAD + size) :
SKB_DATA_ALIGN(size);
-#endif
+
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,
rx_buffer->page_offset, size, truesize);
-#if (PAGE_SIZE < 8192)
- rx_buffer->page_offset ^= truesize;
-#else
- rx_buffer->page_offset += truesize;
-#endif
+
+ if (PAGE_SIZE < 8192)
+ rx_buffer->page_offset ^= truesize;
+ else
+ rx_buffer->page_offset += truesize;
}
static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
@@ -8494,16 +8490,16 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
struct xdp_buff *xdp,
ktime_t timestamp)
{
-#if (PAGE_SIZE < 8192)
- unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
-#else
- unsigned int truesize = SKB_DATA_ALIGN(xdp->data_end -
- xdp->data_hard_start);
-#endif
unsigned int size = xdp->data_end - xdp->data;
+ unsigned int truesize;
unsigned int headlen;
struct sk_buff *skb;
+ if (PAGE_SIZE < 8192)
+ truesize = igb_rx_pg_size(rx_ring) / 2;
+ else
+ truesize = SKB_DATA_ALIGN(xdp->data_end - xdp->data_hard_start);
+
/* prefetch first cache line of first page */
net_prefetch(xdp->data);
@@ -8529,11 +8525,10 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
skb_add_rx_frag(skb, 0, rx_buffer->page,
(xdp->data + headlen) - page_address(rx_buffer->page),
size, truesize);
-#if (PAGE_SIZE < 8192)
- rx_buffer->page_offset ^= truesize;
-#else
- rx_buffer->page_offset += truesize;
-#endif
+ if (PAGE_SIZE < 8192)
+ rx_buffer->page_offset ^= truesize;
+ else
+ rx_buffer->page_offset += truesize;
} else {
rx_buffer->pagecnt_bias++;
}
@@ -8546,16 +8541,17 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring,
struct xdp_buff *xdp,
ktime_t timestamp)
{
-#if (PAGE_SIZE < 8192)
- unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
-#else
- unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
- SKB_DATA_ALIGN(xdp->data_end -
- xdp->data_hard_start);
-#endif
unsigned int metasize = xdp->data - xdp->data_meta;
+ unsigned int truesize;
struct sk_buff *skb;
+ if (PAGE_SIZE < 8192)
+ truesize = igb_rx_pg_size(rx_ring) / 2;
+ else
+ truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
+ SKB_DATA_ALIGN(xdp->data_end -
+ xdp->data_hard_start);
+
/* prefetch first cache line of first page */
net_prefetch(xdp->data_meta);
@@ -8575,11 +8571,10 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring,
skb_hwtstamps(skb)->hwtstamp = timestamp;
/* update buffer offset */
-#if (PAGE_SIZE < 8192)
- rx_buffer->page_offset ^= truesize;
-#else
- rx_buffer->page_offset += truesize;
-#endif
+ if (PAGE_SIZE < 8192)
+ rx_buffer->page_offset ^= truesize;
+ else
+ rx_buffer->page_offset += truesize;
return skb;
}
@@ -8634,14 +8629,14 @@ static unsigned int igb_rx_frame_truesize(struct igb_ring *rx_ring,
{
unsigned int truesize;
-#if (PAGE_SIZE < 8192)
- truesize = igb_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
-#else
- truesize = ring_uses_build_skb(rx_ring) ?
- SKB_DATA_ALIGN(IGB_SKB_PAD + size) +
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
- SKB_DATA_ALIGN(size);
-#endif
+ if (PAGE_SIZE < 8192)
+ truesize = igb_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
+ else
+ truesize = ring_uses_build_skb(rx_ring) ?
+ SKB_DATA_ALIGN(IGB_SKB_PAD + size) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
+ SKB_DATA_ALIGN(size);
+
return truesize;
}
@@ -8650,11 +8645,11 @@ static void igb_rx_buffer_flip(struct igb_ring *rx_ring,
unsigned int size)
{
unsigned int truesize = igb_rx_frame_truesize(rx_ring, size);
-#if (PAGE_SIZE < 8192)
- rx_buffer->page_offset ^= truesize;
-#else
- rx_buffer->page_offset += truesize;
-#endif
+
+ if (PAGE_SIZE < 8192)
+ rx_buffer->page_offset ^= truesize;
+ else
+ rx_buffer->page_offset += truesize;
}
static inline void igb_rx_checksum(struct igb_ring *ring,
@@ -8825,12 +8820,12 @@ static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring,
struct igb_rx_buffer *rx_buffer;
rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
- *rx_buf_pgcnt =
-#if (PAGE_SIZE < 8192)
- page_count(rx_buffer->page);
-#else
- 0;
-#endif
+
+ if (PAGE_SIZE < 8192)
+ *rx_buf_pgcnt = page_count(rx_buffer->page);
+ else
+ *rx_buf_pgcnt = 0;
+
prefetchw(rx_buffer->page);
/* we are reusing so sync this buffer for CPU use */
@@ -8881,9 +8876,8 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
int rx_buf_pgcnt;
/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
-#if (PAGE_SIZE < 8192)
- frame_sz = igb_rx_frame_truesize(rx_ring, 0);
-#endif
+ if (PAGE_SIZE < 8192)
+ frame_sz = igb_rx_frame_truesize(rx_ring, 0);
xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq);
while (likely(total_packets < budget)) {
@@ -8932,10 +8926,9 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
xdp_prepare_buff(&xdp, hard_start, offset, size, true);
xdp_buff_clear_frags_flag(&xdp);
-#if (PAGE_SIZE > 4096)
/* At larger PAGE_SIZE, frame_sz depend on len size */
- xdp.frame_sz = igb_rx_frame_truesize(rx_ring, size);
-#endif
+ if (PAGE_SIZE > 4096)
+ xdp.frame_sz = igb_rx_frame_truesize(rx_ring, size);
skb = igb_run_xdp(adapter, rx_ring, &xdp);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [RFC PATCH v1 13/57] bpf: Remove PAGE_SIZE compile-time constant assumption
2024-10-14 10:58 ` [RFC PATCH v1 13/57] bpf: Remove PAGE_SIZE compile-time constant assumption Ryan Roberts
@ 2024-10-16 14:38 ` Ryan Roberts
0 siblings, 0 replies; 4+ messages in thread
From: Ryan Roberts @ 2024-10-16 14:38 UTC (permalink / raw)
To: Alexei Starovoitov, Andrew Morton, Anshuman Khandual,
Ard Biesheuvel, Catalin Marinas, Daniel Borkmann,
David Hildenbrand, Greg Marsden, Ivan Ivanov, Kalesh Singh,
Marc Zyngier, Mark Rutland, Matthias Brugger, Miroslav Benes,
Will Deacon, Andrii Nakryiko
Cc: bpf, linux-arm-kernel, linux-kernel, linux-mm
+ Andrii Nakryiko
This was a rather tricky series to get the recipients correct for and my script
did not realize that "supporter" was a pseudonym for "maintainer" so you were
missed off the original post. Appologies!
More context in cover letter:
https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/
On 14/10/2024 11:58, Ryan Roberts wrote:
> To prepare for supporting boot-time page size selection, refactor code
> to remove assumptions about PAGE_SIZE being compile-time constant. Code
> intended to be equivalent when compile-time page size is active.
>
> Refactor "struct bpf_ringbuf" so that consumer_pos, producer_pos,
> pending_pos and data are no longer embedded at (static) page offsets
> within the struct. This can't work for boot-time page size because the
> page size isn't known at compile-time. Instead, only define the meta
> data in the struct, along with pointers to those values. At "struct
> bpf_ringbuf" allocation time, the extra pages are allocated at the end
> and the pointers are initialized to point to the correct locations.
>
> Additionally, only expose the __PAGE_SIZE enum to BTF for compile-time
> page size builds. We don't know the page size at compile-time for
> boot-time builds. NOTE: This may need some extra thought; perhaps
> __PAGE_SIZE should be exposed as 0 in this case? And/or perhaps
> __PAGE_SIZE_MIN/__PAGE_SIZE_MAX should be exposed? And there would need
> to be a runtime mechanism for querying the page size (e.g.
> getpagesize()).
>
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> ---
>
> ***NOTE***
> Any confused maintainers may want to read the cover note here for context:
> https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/
>
> kernel/bpf/core.c | 9 ++++++--
> kernel/bpf/ringbuf.c | 54 ++++++++++++++++++++++++--------------------
> 2 files changed, 37 insertions(+), 26 deletions(-)
>
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 7ee62e38faf0e..485875aa78e63 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -89,10 +89,15 @@ void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb, int k, uns
> return NULL;
> }
>
> -/* tell bpf programs that include vmlinux.h kernel's PAGE_SIZE */
> +/*
> + * tell bpf programs that include vmlinux.h kernel's PAGE_SIZE. We can only do
> + * this for compile-time PAGE_SIZE builds.
> + */
> +#if PAGE_SIZE_MIN == PAGE_SIZE_MAX
> enum page_size_enum {
> __PAGE_SIZE = PAGE_SIZE
> };
> +#endif
>
> struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flags)
> {
> @@ -100,7 +105,7 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
> struct bpf_prog_aux *aux;
> struct bpf_prog *fp;
>
> - size = round_up(size, __PAGE_SIZE);
> + size = round_up(size, PAGE_SIZE);
> fp = __vmalloc(size, gfp_flags);
> if (fp == NULL)
> return NULL;
> diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
> index e20b90c361316..8e4093ddbc638 100644
> --- a/kernel/bpf/ringbuf.c
> +++ b/kernel/bpf/ringbuf.c
> @@ -14,9 +14,9 @@
>
> #define RINGBUF_CREATE_FLAG_MASK (BPF_F_NUMA_NODE)
>
> -/* non-mmap()'able part of bpf_ringbuf (everything up to consumer page) */
> +/* non-mmap()'able part of bpf_ringbuf (everything defined in struct) */
> #define RINGBUF_PGOFF \
> - (offsetof(struct bpf_ringbuf, consumer_pos) >> PAGE_SHIFT)
> + (PAGE_ALIGN(sizeof(struct bpf_ringbuf)) >> PAGE_SHIFT)
> /* consumer page and producer page */
> #define RINGBUF_POS_PAGES 2
> #define RINGBUF_NR_META_PAGES (RINGBUF_PGOFF + RINGBUF_POS_PAGES)
> @@ -69,10 +69,10 @@ struct bpf_ringbuf {
> * validate each sample to ensure that they're correctly formatted, and
> * fully contained within the ring buffer.
> */
> - unsigned long consumer_pos __aligned(PAGE_SIZE);
> - unsigned long producer_pos __aligned(PAGE_SIZE);
> - unsigned long pending_pos;
> - char data[] __aligned(PAGE_SIZE);
> + unsigned long *consumer_pos;
> + unsigned long *producer_pos;
> + unsigned long *pending_pos;
> + char *data;
> };
>
> struct bpf_ringbuf_map {
> @@ -134,9 +134,15 @@ static struct bpf_ringbuf *bpf_ringbuf_area_alloc(size_t data_sz, int numa_node)
> rb = vmap(pages, nr_meta_pages + 2 * nr_data_pages,
> VM_MAP | VM_USERMAP, PAGE_KERNEL);
> if (rb) {
> + void *base = rb;
> +
> kmemleak_not_leak(pages);
> rb->pages = pages;
> rb->nr_pages = nr_pages;
> + rb->consumer_pos = (unsigned long *)(base + PAGE_SIZE * RINGBUF_PGOFF);
> + rb->producer_pos = (unsigned long *)(base + PAGE_SIZE * (RINGBUF_PGOFF + 1));
> + rb->pending_pos = rb->producer_pos + 1;
> + rb->data = base + PAGE_SIZE * nr_meta_pages;
> return rb;
> }
>
> @@ -179,9 +185,9 @@ static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node)
> init_irq_work(&rb->work, bpf_ringbuf_notify);
>
> rb->mask = data_sz - 1;
> - rb->consumer_pos = 0;
> - rb->producer_pos = 0;
> - rb->pending_pos = 0;
> + *rb->consumer_pos = 0;
> + *rb->producer_pos = 0;
> + *rb->pending_pos = 0;
>
> return rb;
> }
> @@ -300,8 +306,8 @@ static unsigned long ringbuf_avail_data_sz(struct bpf_ringbuf *rb)
> {
> unsigned long cons_pos, prod_pos;
>
> - cons_pos = smp_load_acquire(&rb->consumer_pos);
> - prod_pos = smp_load_acquire(&rb->producer_pos);
> + cons_pos = smp_load_acquire(rb->consumer_pos);
> + prod_pos = smp_load_acquire(rb->producer_pos);
> return prod_pos - cons_pos;
> }
>
> @@ -418,7 +424,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
> if (len > ringbuf_total_data_sz(rb))
> return NULL;
>
> - cons_pos = smp_load_acquire(&rb->consumer_pos);
> + cons_pos = smp_load_acquire(rb->consumer_pos);
>
> if (in_nmi()) {
> if (!spin_trylock_irqsave(&rb->spinlock, flags))
> @@ -427,8 +433,8 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
> spin_lock_irqsave(&rb->spinlock, flags);
> }
>
> - pend_pos = rb->pending_pos;
> - prod_pos = rb->producer_pos;
> + pend_pos = *rb->pending_pos;
> + prod_pos = *rb->producer_pos;
> new_prod_pos = prod_pos + len;
>
> while (pend_pos < prod_pos) {
> @@ -440,7 +446,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
> tmp_size = round_up(tmp_size + BPF_RINGBUF_HDR_SZ, 8);
> pend_pos += tmp_size;
> }
> - rb->pending_pos = pend_pos;
> + *rb->pending_pos = pend_pos;
>
> /* check for out of ringbuf space:
> * - by ensuring producer position doesn't advance more than
> @@ -460,7 +466,7 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
> hdr->pg_off = pg_off;
>
> /* pairs with consumer's smp_load_acquire() */
> - smp_store_release(&rb->producer_pos, new_prod_pos);
> + smp_store_release(rb->producer_pos, new_prod_pos);
>
> spin_unlock_irqrestore(&rb->spinlock, flags);
>
> @@ -506,7 +512,7 @@ static void bpf_ringbuf_commit(void *sample, u64 flags, bool discard)
> * new data availability
> */
> rec_pos = (void *)hdr - (void *)rb->data;
> - cons_pos = smp_load_acquire(&rb->consumer_pos) & rb->mask;
> + cons_pos = smp_load_acquire(rb->consumer_pos) & rb->mask;
>
> if (flags & BPF_RB_FORCE_WAKEUP)
> irq_work_queue(&rb->work);
> @@ -580,9 +586,9 @@ BPF_CALL_2(bpf_ringbuf_query, struct bpf_map *, map, u64, flags)
> case BPF_RB_RING_SIZE:
> return ringbuf_total_data_sz(rb);
> case BPF_RB_CONS_POS:
> - return smp_load_acquire(&rb->consumer_pos);
> + return smp_load_acquire(rb->consumer_pos);
> case BPF_RB_PROD_POS:
> - return smp_load_acquire(&rb->producer_pos);
> + return smp_load_acquire(rb->producer_pos);
> default:
> return 0;
> }
> @@ -680,12 +686,12 @@ static int __bpf_user_ringbuf_peek(struct bpf_ringbuf *rb, void **sample, u32 *s
> u64 cons_pos, prod_pos;
>
> /* Synchronizes with smp_store_release() in user-space producer. */
> - prod_pos = smp_load_acquire(&rb->producer_pos);
> + prod_pos = smp_load_acquire(rb->producer_pos);
> if (prod_pos % 8)
> return -EINVAL;
>
> /* Synchronizes with smp_store_release() in __bpf_user_ringbuf_sample_release() */
> - cons_pos = smp_load_acquire(&rb->consumer_pos);
> + cons_pos = smp_load_acquire(rb->consumer_pos);
> if (cons_pos >= prod_pos)
> return -ENODATA;
>
> @@ -715,7 +721,7 @@ static int __bpf_user_ringbuf_peek(struct bpf_ringbuf *rb, void **sample, u32 *s
> * Update the consumer pos, and return -EAGAIN so the caller
> * knows to skip this sample and try to read the next one.
> */
> - smp_store_release(&rb->consumer_pos, cons_pos + total_len);
> + smp_store_release(rb->consumer_pos, cons_pos + total_len);
> return -EAGAIN;
> }
>
> @@ -737,9 +743,9 @@ static void __bpf_user_ringbuf_sample_release(struct bpf_ringbuf *rb, size_t siz
> * prevents another task from writing to consumer_pos after it was read
> * by this task with smp_load_acquire() in __bpf_user_ringbuf_peek().
> */
> - consumer_pos = rb->consumer_pos;
> + consumer_pos = *rb->consumer_pos;
> /* Synchronizes with smp_load_acquire() in user-space producer. */
> - smp_store_release(&rb->consumer_pos, consumer_pos + rounded_size);
> + smp_store_release(rb->consumer_pos, consumer_pos + rounded_size);
> }
>
> BPF_CALL_4(bpf_user_ringbuf_drain, struct bpf_map *, map,
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC PATCH v1 29/57] net: igb: Remove PAGE_SIZE compile-time constant assumption
2024-10-14 10:58 ` [RFC PATCH v1 29/57] net: igb: " Ryan Roberts
@ 2024-10-16 14:45 ` Ryan Roberts
0 siblings, 0 replies; 4+ messages in thread
From: Ryan Roberts @ 2024-10-16 14:45 UTC (permalink / raw)
To: David S. Miller, Andrew Morton, Anshuman Khandual, Ard Biesheuvel,
Catalin Marinas, David Hildenbrand, Eric Dumazet, Greg Marsden,
Ivan Ivanov, Jakub Kicinski, Kalesh Singh, Marc Zyngier,
Mark Rutland, Matthias Brugger, Miroslav Benes, Paolo Abeni,
Will Deacon, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer, John Fastabend, Przemek Kitszel,
Tony Nguyen
Cc: bpf, intel-wired-lan, linux-arm-kernel, linux-kernel, linux-mm,
netdev
+ Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
Przemek Kitszel, Tony Nguyen
This was a rather tricky series to get the recipients correct for and my script
did not realize that "supporter" was a pseudonym for "maintainer" so you were
missed off the original post. Appologies!
More context in cover letter:
https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/
On 14/10/2024 11:58, Ryan Roberts wrote:
> To prepare for supporting boot-time page size selection, refactor code
> to remove assumptions about PAGE_SIZE being compile-time constant. Code
> intended to be equivalent when compile-time page size is active.
>
> Convert CPP conditionals to C conditionals. The compiler will dead code
> strip when doing a compile-time page size build, for the same end
> effect. But this will also work with boot-time page size builds.
>
> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
> ---
>
> ***NOTE***
> Any confused maintainers may want to read the cover note here for context:
> https://lore.kernel.org/all/20241014105514.3206191-1-ryan.roberts@arm.com/
>
> drivers/net/ethernet/intel/igb/igb.h | 25 ++--
> drivers/net/ethernet/intel/igb/igb_main.c | 149 +++++++++++-----------
> 2 files changed, 82 insertions(+), 92 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
> index 3c2dc7bdebb50..04aeebcd363b3 100644
> --- a/drivers/net/ethernet/intel/igb/igb.h
> +++ b/drivers/net/ethernet/intel/igb/igb.h
> @@ -158,7 +158,6 @@ struct vf_mac_filter {
> * up negative. In these cases we should fall back to the 3K
> * buffers.
> */
> -#if (PAGE_SIZE < 8192)
> #define IGB_MAX_FRAME_BUILD_SKB (IGB_RXBUFFER_1536 - NET_IP_ALIGN)
> #define IGB_2K_TOO_SMALL_WITH_PADDING \
> ((NET_SKB_PAD + IGB_TS_HDR_LEN + IGB_RXBUFFER_1536) > SKB_WITH_OVERHEAD(IGB_RXBUFFER_2048))
> @@ -177,6 +176,9 @@ static inline int igb_skb_pad(void)
> {
> int rx_buf_len;
>
> + if (PAGE_SIZE >= 8192)
> + return NET_SKB_PAD + NET_IP_ALIGN;
> +
> /* If a 2K buffer cannot handle a standard Ethernet frame then
> * optimize padding for a 3K buffer instead of a 1.5K buffer.
> *
> @@ -196,9 +198,6 @@ static inline int igb_skb_pad(void)
> }
>
> #define IGB_SKB_PAD igb_skb_pad()
> -#else
> -#define IGB_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
> -#endif
>
> /* How many Rx Buffers do we bundle into one write to the hardware ? */
> #define IGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */
> @@ -280,7 +279,7 @@ struct igb_tx_buffer {
> struct igb_rx_buffer {
> dma_addr_t dma;
> struct page *page;
> -#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536)
> +#if (BITS_PER_LONG > 32) || (PAGE_SIZE_MAX >= 65536)
> __u32 page_offset;
> #else
> __u16 page_offset;
> @@ -403,22 +402,20 @@ enum e1000_ring_flags_t {
>
> static inline unsigned int igb_rx_bufsz(struct igb_ring *ring)
> {
> -#if (PAGE_SIZE < 8192)
> - if (ring_uses_large_buffer(ring))
> - return IGB_RXBUFFER_3072;
> + if (PAGE_SIZE < 8192) {
> + if (ring_uses_large_buffer(ring))
> + return IGB_RXBUFFER_3072;
>
> - if (ring_uses_build_skb(ring))
> - return IGB_MAX_FRAME_BUILD_SKB;
> -#endif
> + if (ring_uses_build_skb(ring))
> + return IGB_MAX_FRAME_BUILD_SKB;
> + }
> return IGB_RXBUFFER_2048;
> }
>
> static inline unsigned int igb_rx_pg_order(struct igb_ring *ring)
> {
> -#if (PAGE_SIZE < 8192)
> - if (ring_uses_large_buffer(ring))
> + if (PAGE_SIZE < 8192 && ring_uses_large_buffer(ring))
> return 1;
> -#endif
> return 0;
> }
>
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index 1ef4cb871452a..4f2c53dece1a2 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -4797,9 +4797,7 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
> static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
> struct igb_ring *rx_ring)
> {
> -#if (PAGE_SIZE < 8192)
> struct e1000_hw *hw = &adapter->hw;
> -#endif
>
> /* set build_skb and buffer size flags */
> clear_ring_build_skb_enabled(rx_ring);
> @@ -4810,12 +4808,11 @@ static void igb_set_rx_buffer_len(struct igb_adapter *adapter,
>
> set_ring_build_skb_enabled(rx_ring);
>
> -#if (PAGE_SIZE < 8192)
> - if (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB ||
> + if (PAGE_SIZE < 8192 &&
> + (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB ||
> IGB_2K_TOO_SMALL_WITH_PADDING ||
> - rd32(E1000_RCTL) & E1000_RCTL_SBP)
> + rd32(E1000_RCTL) & E1000_RCTL_SBP))
> set_ring_uses_large_buffer(rx_ring);
> -#endif
> }
>
> /**
> @@ -5314,12 +5311,10 @@ static void igb_set_rx_mode(struct net_device *netdev)
> E1000_RCTL_VFE);
> wr32(E1000_RCTL, rctl);
>
> -#if (PAGE_SIZE < 8192)
> - if (!adapter->vfs_allocated_count) {
> + if (PAGE_SIZE < 8192 && !adapter->vfs_allocated_count) {
> if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
> rlpml = IGB_MAX_FRAME_BUILD_SKB;
> }
> -#endif
> wr32(E1000_RLPML, rlpml);
>
> /* In order to support SR-IOV and eventually VMDq it is necessary to set
> @@ -5338,11 +5333,10 @@ static void igb_set_rx_mode(struct net_device *netdev)
>
> /* enable Rx jumbo frames, restrict as needed to support build_skb */
> vmolr &= ~E1000_VMOLR_RLPML_MASK;
> -#if (PAGE_SIZE < 8192)
> - if (adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
> + if (PAGE_SIZE < 8192 &&
> + adapter->max_frame_size <= IGB_MAX_FRAME_BUILD_SKB)
> vmolr |= IGB_MAX_FRAME_BUILD_SKB;
> else
> -#endif
> vmolr |= MAX_JUMBO_FRAME_SIZE;
> vmolr |= E1000_VMOLR_LPE;
>
> @@ -8435,17 +8429,17 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
> if (!dev_page_is_reusable(page))
> return false;
>
> -#if (PAGE_SIZE < 8192)
> - /* if we are only owner of page we can reuse it */
> - if (unlikely((rx_buf_pgcnt - pagecnt_bias) > 1))
> - return false;
> -#else
> + if (PAGE_SIZE < 8192) {
> + /* if we are only owner of page we can reuse it */
> + if (unlikely((rx_buf_pgcnt - pagecnt_bias) > 1))
> + return false;
> + } else {
> #define IGB_LAST_OFFSET \
> (SKB_WITH_OVERHEAD(PAGE_SIZE) - IGB_RXBUFFER_2048)
>
> - if (rx_buffer->page_offset > IGB_LAST_OFFSET)
> - return false;
> -#endif
> + if (rx_buffer->page_offset > IGB_LAST_OFFSET)
> + return false;
> + }
>
> /* If we have drained the page fragment pool we need to update
> * the pagecnt_bias and page count so that we fully restock the
> @@ -8473,20 +8467,22 @@ static void igb_add_rx_frag(struct igb_ring *rx_ring,
> struct sk_buff *skb,
> unsigned int size)
> {
> -#if (PAGE_SIZE < 8192)
> - unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
> -#else
> - unsigned int truesize = ring_uses_build_skb(rx_ring) ?
> + unsigned int truesize;
> +
> + if (PAGE_SIZE < 8192)
> + truesize = igb_rx_pg_size(rx_ring) / 2;
> + else
> + truesize = ring_uses_build_skb(rx_ring) ?
> SKB_DATA_ALIGN(IGB_SKB_PAD + size) :
> SKB_DATA_ALIGN(size);
> -#endif
> +
> skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_buffer->page,
> rx_buffer->page_offset, size, truesize);
> -#if (PAGE_SIZE < 8192)
> - rx_buffer->page_offset ^= truesize;
> -#else
> - rx_buffer->page_offset += truesize;
> -#endif
> +
> + if (PAGE_SIZE < 8192)
> + rx_buffer->page_offset ^= truesize;
> + else
> + rx_buffer->page_offset += truesize;
> }
>
> static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
> @@ -8494,16 +8490,16 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
> struct xdp_buff *xdp,
> ktime_t timestamp)
> {
> -#if (PAGE_SIZE < 8192)
> - unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
> -#else
> - unsigned int truesize = SKB_DATA_ALIGN(xdp->data_end -
> - xdp->data_hard_start);
> -#endif
> unsigned int size = xdp->data_end - xdp->data;
> + unsigned int truesize;
> unsigned int headlen;
> struct sk_buff *skb;
>
> + if (PAGE_SIZE < 8192)
> + truesize = igb_rx_pg_size(rx_ring) / 2;
> + else
> + truesize = SKB_DATA_ALIGN(xdp->data_end - xdp->data_hard_start);
> +
> /* prefetch first cache line of first page */
> net_prefetch(xdp->data);
>
> @@ -8529,11 +8525,10 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
> skb_add_rx_frag(skb, 0, rx_buffer->page,
> (xdp->data + headlen) - page_address(rx_buffer->page),
> size, truesize);
> -#if (PAGE_SIZE < 8192)
> - rx_buffer->page_offset ^= truesize;
> -#else
> - rx_buffer->page_offset += truesize;
> -#endif
> + if (PAGE_SIZE < 8192)
> + rx_buffer->page_offset ^= truesize;
> + else
> + rx_buffer->page_offset += truesize;
> } else {
> rx_buffer->pagecnt_bias++;
> }
> @@ -8546,16 +8541,17 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring,
> struct xdp_buff *xdp,
> ktime_t timestamp)
> {
> -#if (PAGE_SIZE < 8192)
> - unsigned int truesize = igb_rx_pg_size(rx_ring) / 2;
> -#else
> - unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
> - SKB_DATA_ALIGN(xdp->data_end -
> - xdp->data_hard_start);
> -#endif
> unsigned int metasize = xdp->data - xdp->data_meta;
> + unsigned int truesize;
> struct sk_buff *skb;
>
> + if (PAGE_SIZE < 8192)
> + truesize = igb_rx_pg_size(rx_ring) / 2;
> + else
> + truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
> + SKB_DATA_ALIGN(xdp->data_end -
> + xdp->data_hard_start);
> +
> /* prefetch first cache line of first page */
> net_prefetch(xdp->data_meta);
>
> @@ -8575,11 +8571,10 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring,
> skb_hwtstamps(skb)->hwtstamp = timestamp;
>
> /* update buffer offset */
> -#if (PAGE_SIZE < 8192)
> - rx_buffer->page_offset ^= truesize;
> -#else
> - rx_buffer->page_offset += truesize;
> -#endif
> + if (PAGE_SIZE < 8192)
> + rx_buffer->page_offset ^= truesize;
> + else
> + rx_buffer->page_offset += truesize;
>
> return skb;
> }
> @@ -8634,14 +8629,14 @@ static unsigned int igb_rx_frame_truesize(struct igb_ring *rx_ring,
> {
> unsigned int truesize;
>
> -#if (PAGE_SIZE < 8192)
> - truesize = igb_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
> -#else
> - truesize = ring_uses_build_skb(rx_ring) ?
> - SKB_DATA_ALIGN(IGB_SKB_PAD + size) +
> - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
> - SKB_DATA_ALIGN(size);
> -#endif
> + if (PAGE_SIZE < 8192)
> + truesize = igb_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
> + else
> + truesize = ring_uses_build_skb(rx_ring) ?
> + SKB_DATA_ALIGN(IGB_SKB_PAD + size) +
> + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
> + SKB_DATA_ALIGN(size);
> +
> return truesize;
> }
>
> @@ -8650,11 +8645,11 @@ static void igb_rx_buffer_flip(struct igb_ring *rx_ring,
> unsigned int size)
> {
> unsigned int truesize = igb_rx_frame_truesize(rx_ring, size);
> -#if (PAGE_SIZE < 8192)
> - rx_buffer->page_offset ^= truesize;
> -#else
> - rx_buffer->page_offset += truesize;
> -#endif
> +
> + if (PAGE_SIZE < 8192)
> + rx_buffer->page_offset ^= truesize;
> + else
> + rx_buffer->page_offset += truesize;
> }
>
> static inline void igb_rx_checksum(struct igb_ring *ring,
> @@ -8825,12 +8820,12 @@ static struct igb_rx_buffer *igb_get_rx_buffer(struct igb_ring *rx_ring,
> struct igb_rx_buffer *rx_buffer;
>
> rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
> - *rx_buf_pgcnt =
> -#if (PAGE_SIZE < 8192)
> - page_count(rx_buffer->page);
> -#else
> - 0;
> -#endif
> +
> + if (PAGE_SIZE < 8192)
> + *rx_buf_pgcnt = page_count(rx_buffer->page);
> + else
> + *rx_buf_pgcnt = 0;
> +
> prefetchw(rx_buffer->page);
>
> /* we are reusing so sync this buffer for CPU use */
> @@ -8881,9 +8876,8 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
> int rx_buf_pgcnt;
>
> /* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
> -#if (PAGE_SIZE < 8192)
> - frame_sz = igb_rx_frame_truesize(rx_ring, 0);
> -#endif
> + if (PAGE_SIZE < 8192)
> + frame_sz = igb_rx_frame_truesize(rx_ring, 0);
> xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq);
>
> while (likely(total_packets < budget)) {
> @@ -8932,10 +8926,9 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
>
> xdp_prepare_buff(&xdp, hard_start, offset, size, true);
> xdp_buff_clear_frags_flag(&xdp);
> -#if (PAGE_SIZE > 4096)
> /* At larger PAGE_SIZE, frame_sz depend on len size */
> - xdp.frame_sz = igb_rx_frame_truesize(rx_ring, size);
> -#endif
> + if (PAGE_SIZE > 4096)
> + xdp.frame_sz = igb_rx_frame_truesize(rx_ring, size);
> skb = igb_run_xdp(adapter, rx_ring, &xdp);
> }
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-10-16 14:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20241014105514.3206191-1-ryan.roberts@arm.com>
[not found] ` <20241014105912.3207374-1-ryan.roberts@arm.com>
2024-10-14 10:58 ` [RFC PATCH v1 13/57] bpf: Remove PAGE_SIZE compile-time constant assumption Ryan Roberts
2024-10-16 14:38 ` Ryan Roberts
2024-10-14 10:58 ` [RFC PATCH v1 29/57] net: igb: " Ryan Roberts
2024-10-16 14:45 ` Ryan Roberts
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox