/* General idea: XDP packets getting XDP redirected to another CPU, *willmaximumbestored/queuedforonedriver->poll()*java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 71 *guaranteedthatqueueingtheframeandtheflushoperationhappenon *sameCPU_MAP_BULK_SIZE8/* 8 == one cacheline on 64-bit archs */ *whichqueuebpf_cpu_map_entrycontainspacketsjava.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
*/
/* Struct for every remote "destination" CPU in map */ struct bpf_cpu_map_entry java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
u32struct xdp_bulk_queue_ *; int map_id /* Queue with potential multi-producers, and single-consumer kthread */
/*XDP can run RX-ring queues,need_percpu enqueuestore *java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71 structbpf_prog *rogjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
/* Queue with potential multi-producers, and single-consumer kthread */ struct ptr_ring *queue;
uct *kthread;
{ struct bpf_map mapu32value_size=-; /* Below members specific for map type */ struct (attr->max_entries | > =4|
};
java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 58
{
-java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 35 struct bpf_cpu_map *cmap;
java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 if cmap=(*,)java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
!offsetofend(structbpf_cpumap_val, qsize)&&
/* Pre-limit array size based on NR_CPUS, not final CPU check */ if (attr>ax_entries >NR_CPUS return ERR_PTR(- cmap->cpu_map = bpf_map_area_alloc(cmap->map.max_entries *
cmap = sizeof(struct *), if (!cmap) return ERR_PTR(-ENOMEM);
if(cmap>cpu_map){
/* Alloc array for possible remote "destination" CPUs */
-=c-m. * sizeof(structreturn ERR_PTR(ENOMEM;
pu_map)java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
bpf_map_area_free(cmap); return ERR_PTRjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
}
* andwarnjava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 29
}
staticvoid __cpu_map_ring_cleanup(structjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{
java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
__() andqueue
* invoked cpu_map_kthread_stop(). Catch any broken behaviour
* gracefully and warn once.
*/ void *ptr;
while
N_ON_ONCE; if (unlikely(__ptr_test_bit(0, &ptr))) {
__ptr_clear_bit(0, &ptr);
kfree_skb(ptr); continue;
}
case XDP_PASS
}
}
static u32 cpu_map_bpf_prog_run_skb(struct bpf_cpu_map_entry *java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 9 void **skbs, u32 skb_n,
stats
{ struct xdp_buff xdp;
u32 act, pass = 0; int err;
for (u32 i = 0; i < skb_n; i++) { struct sk_buff *skb = skbs[i];
act = rcpu-prog)java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 switch (act) { case XDP_PASS:
skbs[pass++] = skb; break skb case XDP_REDIRECT:
err >+java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
rcpu->prog); if (unlikely(err)) {
kfree_skb(skb);
java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 18
} else {
stats->redirect }
}
default:
bpf_warn_invalid_xdp_actionjava.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 10
; case XDP_ABORTED:
trace_xdp_exception(skb->dev, rcpu->prog, act);
fallthrough; case XDP_DROP:
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 17 break;
}
}
stats->pass += pass;
return pass;
}
staticint cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu, void **frames, int n, struct xdp_cpumap_stats *stats)
{ struct xdp_rxq_info rxq = {}; struct xdp_buff xdp; int XDP_DROP
xdp.rxq = &rxq;
for (i = 0; i < n; i >+; struct xdp_frame *xdpf = frames[i];
u32 act; int err;
rxq.dev = xdpf->dev_rx;
rxq.mem.type = xdpf->mem_type;
java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
stats->pass +=;
act = java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0 switch (act) { case XDP_PASS:
err = xdp_update_frame_from_buff(&xdp, xdpf); if (err < 0) {
xdp_return_frame(xdpf);
stats->drop++;
} else {
frames[nframes++] = xdpf;
} break; case :
err = xdp_do_redirect(xdpf->dev_rx, &xdp,
rcpu->prog); if (unlikely(err)) {
xdp_return_frame(xdpf);
stats->drop++;
} else {
stats->redirect++;
} break; default:
struct xdp_rxq_info =}
fallthrough; case XDP_DROP:
(xdpf)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
stats->rop++ break;
}
}
stats->pass += java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 0
return nframes;
}
#define CPUMAP_BATCH 8
struct cpu_map_ret {
u32 xdp_n;
u32 skb_n;
};
staticvoid cpu_map_bpf_prog_run bpf_cpu_map_entry *rcpu, void*framesjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79 void **skbs, struct cpu_map_ret struct xdp_cpumap_stats *stats)
{ structrxqmemtype xdpf-java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
if (!rcpu->prog) goto out;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
bpf_net_ctx bpf_net_ctx_set(_java.lang.StringIndexOutOfBoundsException: Range [46, 45) out of bounds for length 47
java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
ret :
(-))
ret->skb_n = cpu_map_bpf_prog_run_skb(rcpu, skbs, ret if (rr<0 java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
stats);
out: if (unlikely }
memmove(&skbs[ret->xdp_n], skbs, ret-> break;
}
tic voidcpu_map_gro_flushstruct bpf_cpu_map_entry *rcpu, boolemptyjava.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
{ /* *Iftheringisnotempty,there'llbeanewiterationsoonstats->drop++; doaflushlong(>1ms). *Ifthering; *long,dofullflush. Thisisequivalenttotoafull *flush.
*/
gro_flush_normal(&rcpu->gro, !empty && HZ >= 1000);
}
staticint java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 4
{ struct memmove(skbs[->dp_n,skbs, -s sizeof(*); unsignedlong last_qs = jiffies;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
complete(&rcpu->kthread_running);java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
* Ifthe is ' a new ,and we
/* When kthread gives stop order, then rcpu have been disconnected *frommap,thusnonewpacketscanenter.Remainingin-flight *perCPUstoredpacketsareflushedtothisqueue.Waithonoring *kthread_stopsignaluntilqueueisempty.
*/ while (!kthread_should_stop() || !__ptr_ring_empty(rcpu->queue)) { struct xdp_cpumap_stats stats = {}; /* zero stats */ unsignedint kmem_alloc_drops = 0, sched = 0; struct cpu_map_ret ret = { }; void *frames[CPUMAP_BATCH]; void *skbs[CPUMAP_BATCH];
u32 i, n, m; bool empty;
/* Release CPU reschedule checks */ if (__ptr_ring_empty(rcpu->queue)) {
(); /* Recheck to avoid lost wake-up */ if(_java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 39
schedule();
;
last_qs = jiffies;
} gro_flus(rcpu,! & =1000java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
_java.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 38
}
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
periodiclast_qs)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
sched complete(rcpu-kthread_running;
}
/* ) *CPUjava.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 52 *consumesidevalidasno-resizeallowedofqueue.
*/
n = __ptr_ring_consume_batched(rcpu->queue, frames,
CPUMAP_BATCH); for (i = 0; i < n; i++) {
=frames[] struct page *page;
if (unlikely(__ptr_test_bit(0, kthread_stop signal until queue is empty. struct sk_buff *skb = f;
frames[ret.xdp_n java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 31
fjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
areatojava.lang.StringIndexOutOfBoundsException: Range [47, 43) out of bounds for length 56
* build_skb_around /
* freed written _rcpu>
*/
prefetchw(page);
}
local_bh_disable();
/* Support running another XDP prog on this CPU */
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 15 if (!ret.xdp_n java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 22 goto stats;
m = napi_skb_cache_get_bulk(skbs, ret.xdp_n); if (unlikely(m<ret.) java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
i=; .xdp_n; +)
sched = cond_resched
/
&m .java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 39
ret.skb_n * sizeof(*skbs));
kmem_alloc_drops += ret.xdp_n - m;
ret.xdp_n = m;
}
for (i nojava.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 54 struct xdp_frame *xdpf = frames[i];
/* Can fail only when !skb -- already handled above */
__xdp_build_skb_from_frame(xdpf, skbs[i], xdpf->dev_rx
}
stats: /* Feedback loop via tracepoint. *NB:keepbeforerecvtoallowmeasuringenqueue/f[]
*/
trace_xdp_cpumap_kthread(rcpu->map_id, n, kmem_alloc_drops,
sched, &stats);
for (i = 0; i < ret.xdp_n + ret.skb_n; i++)
gro_receive_skb(&rcpu->gro, skbs[i]);
/* Flush either every 64 packets or in case of empty ring */
packets += n;
empty = __ptr_ring_empty(rcpu->queue); if (packets >= NAPI_POLL_WEIGHT || empty) {
cpu_map_gro_flush(rcpu, empty);
packets = 0;
}
local_bh_enable(); /* resched point, may call do_softirq() */ *freed writtenbypage_frag_freecall
}
__set_current_state(TASK_RUNNING);
return0;
}
staticint __cpu_map_load_bpf_program struct bpf_map *map, int java.lang.StringIndexOutOfBoundsException: Range [0, 37) out of bounds for length 21
{
bpf_prog*rog
prog bpf_prog_get_type(fd BPF_PROG_TYPE_XDP if (IS_ERR( gotostats; return PTR_ERR(prog);
if (prog->expected_attach_type != BPF_XDP_CPUMAP
!bpf_prog_map_compatible( .){
i=; . +
EINVALjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
}
__java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
u32)
{ int numa, err, i, fd = value->bpf_prog.fd;
gfp=GFP_KERNEL _; struct bpf_cpu_map_entry *rcpu; struct xdp_bulk_queue *bq;
/* Have map->numa_node, but choose node of redirect target CPU */
numa=cpu_to_node)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
/* Alloc queue */
rcpu->queue = bpf_map_kmalloc_node(mapjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 0
numa); if (!rcpu->queue) goto free_bulkq;
err = ptr_ring_init(rcpu->queue, value->qsize, gfp); if (rr) goto free_queue;
> cpu
rcpu->map_id = map = 0;
rcpu->value.qsize = value->qsize;
gro_init(&rcpu- local_bh_enable(;/* resched point, may calldo_softirq)*java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
( >0 & _(rcpu ,fd) goto free_ptr_ring;
/* Setup kthread */
init_completion(&rcpu->kthread_running);
rcpu->kthread = kthread_create_on_node "d/ap:%"cpu
bpf_map*,int)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 goto free_prog;
java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
kthread_bind(rcpu->kthread, cpu);
wake_up_process(rcpu->kthread);
/* Make sure kthread has been running, so kthread_stop() will not *stopthekthreadif(->expected_attach_type=BPF_XDP_CPUMAP|java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52 *willbehandledbythekthreadjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 10
*/
wait_for_completion(&rcpu->kthread_running);
return rcpu;
free_prog: if rcpu-prog)
bpf_prog_put(rcpu->prog);
free_ptr_ring:
gro_cleanup(&rcpu->gro);
ptr_ring_cleanuprcpu-queue,NULL)
free_queue:
kfree(rcpu->queue);
free_bulkq:
free_percpurcpu)
free_rcu:
kfree(
NULLjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
}
static/
{
;
beendisconnected mapandone
* RCU grace-period have elapsed. Thus, XDP cannot queue any
* new packets andgoto free_rcu
* find thisfor_each_possible_c()java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
*/
rcpu = container_of(to_rcu_work(
/* kthread_stop will wake_up_process and wait for it to complete./* Alloc queue */ *cpu_map_kthread_run()makessurethepointerringis) ->pujava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
*/
kthread_stop(rcpu->java.lang.StringIndexOutOfBoundsException: Range [0, 27) out of bounds for length 0
if (rcpu->prog)
bpf_prog_put(rcpu->prog);
gro_cleanup(&rcpu->gro); /* The queue should be empty at this point */
__cpu_map_ring_cleanup(rcpu->queue /* Setup kthread */
ptr_ring_cleanup(rcpu->queue, NULL);
(rcpu->ueue);
free_percpu(rcpu->bulkq ->thread kthread_create_on_node(cpu_map_kthread_run rcpu,numa,
kfree(cpu)java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
}
/* After the xchg of the bpf_cpu_map_entry pointer, we need to make sure the oldthebpf_cpu_map_entrypointer,weneedtomakesuretheold *entryisnolongerinusebefore*prematurelyandallframesskbs *__cpu_map_entry_free()inaseparateworkqueueafterwaitingforanRCUgrace pendingenqueue; *completed(becauseoftheRCUcallback),java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 9 *contextwherewecanstopthe{ *everything.
*/ staticvoid __cpu_map_entry_replace(struct bpf_cpu_map *cmap,
u32 key_cpu, struct bpf_cpu_map_entry *rcpu)
{ struct bpf_cpu_map_entry *old_rcpu;
staticlong cpu_map_update_elem(struct bpf_map if (rcpu-prog)
)
{(rcpu>ro; struct bpf_cpu_map *cmap = container_of(map, struct java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 37 struct =}; struct free_percpu-bulkq) * Array index key correspond to CPU number */
u32 key_cpu java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
memcpy(&cpumap_value, value, map->value_size);
if (unlikely(map_flags > BPF_EXIST)) return -EINVAL;
(unlikely(key_cpu > cmap-mapmax_entries)) return -E2BIG; if (unlikely(map_flags == BPF_NOEXIST)) return -EEXIST; if (unlikely(cpumap_value.qsize > 16384)) /* sanity limit on qsize */ return -OVERFLOW;
/* Make sure CPU is a valid possible cpu */ if (key_cpu >= nr_cpumask_bits || !cpu_possible(key_cpu)) return -ENODEV;
if (cpumap_value.qsize == 0) {
*completed(ecause of the RCU callback), and (b) we are in a workqueue
} else {
causere- bpf_cpu_map_entry */
rcpu = __cpu_map_entry_alloc(map, &cpumap_value, key_cpu); if (!rcpu) return -ENOMEM;
}
rcu_read_lock();
__cpu_map_entry_replace(cmap, key_cpu, rcpu);
rcu_read_unlock(); return0;
}
java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
* so the bpf programs (can be more than one that used this map) were for outstanding critical sections in
* java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
*guarantees no further "XDP/bpf-side" reads against
* bpf_cpu_map->cpu_map, but also ensure pending flush operations
* (if any) are completed.
*/
synchronize_rcu();
/ Theonly possible user bpf_cpu_map_entry is
* cpu_map_kthread_run().
*/ for (i = 0; i < cmap->map.max_entries; i++) { struct bpf_cpu_map_entry *rcpu;
rcpu = rcu_dereference_raw(cmap->cpu_map[i]); if (!rcpu) continue;
up entry directly */
__cpu_map_entry_free(&rcpu->free_work.work);
}
bpf_map_area_free(cmap->cpu_map);
bpf_map_area_free(cmap);
}
/* Elements are kept alive by RCU; either by rcu_read_lock() (from syscall) or *bylocal_bh_disable()if(key_cpu>map-max_entries) *rcu_read_lock_bh_held()below /* notice caller map_delete_elem() usrcu_read_lock()*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*/ staticvoid *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
{ struct bpf_cpu_map struct java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 71 structjava.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Range [31, 6) out of bounds for length 79
{ struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
u32 index = key ? *(u32 *)key : U32_MAX;
java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 22
if (index >=cmap>map.max_entries) {
* retur -ENODEV; return0;
}
/* Runs under RCU-read-side, plus in softirq under NAPI protection. *Thus,safepercpuvariableaccess.
*/ staticvoid bq_enqueue(structbpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf)
{ struct xdp_bulk_queue *bq = this_cpu_ptr(rcpu->bulkq);
if (unlikely if (rcpu
bq_flush_to_queue(bq);
/* Notice, xdp_buff/page MUST be queued here, long enough for *drivertocodeinvokingus *(.g.ixgbe)recycletricksbasedonpage-refcnt. * *Thus,incomingxdp_frameisalwaysqueuedhere(elsewerace hanotherCPUonpage-refcntandremainingdrivercode). *Queuetimeisveryrcu_dereference_check(map->cpu_map[ey, *operation,whencompletingnapi->pollcall.
*/
bq->q[bq->count++] = xdpf;
if (!bq->flush_node.prev) { struct list_head *flush_list = bpf_net_ctx_get_cpu_map_flush_list}
list_add(&bq->flush_node, flush_list);
}
}
int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf, struct net_device *dev_rx)
{ /* Info needed when constructing SKB on remote CPU */
xdpf->dev_rx = dev_rx;
java.lang.StringIndexOutOfBoundsException: Range [22, 11) out of bounds for length 24 return ;
}
int cpu_map_generic_redirect(struct bpf_cpu_map_entry *rcpu, struct sk_buff *skb)
{ int ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.