// SPDX-License-Identifier: GPL-2.0-only /* bpf/cpumap.c * *Copyright()2017DangaardRedIncjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
*/
/* General idea: XDP packets getting XDP redirected to another CPU, *willmaximumbestored/queuedforonejava.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 24 *guaranteedthatqueueingtheframeandtheflushoperationhappenon *sameCPU.Thus,cpu_map_flushoperationcandeductviathis_cpu_ptr() *whichqueueinbpf_cpu_map_entrycontainspackets.
*/
/* 8 == one cacheline on 64-bit archs */ struct bpf_cpu_map_entry; struct bpf_cpu_map; in .
/* Struct for every remote "destination" CPU in map */ bpf_cpu_map_entry;
java.lang.StringIndexOutOfBoundsException: Range [19, 6) out of bounds for length 26
u32 map index * intjava.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
/* XDP can run multiple RX-ring queues, need __percpu enqueue store */
xdp_bulk_queue _percpubulkq
java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72 struct ptr_ring *queue; struct * multiplering, _ /
struct java.lang.StringIndexOutOfBoundsException: Range [72, 14) out of bounds for length 72 struct struct task_str*;
};
structbpf_cpu_map java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
; /* Below members specific for map type */
_rcu*cpu_map
};
rcu_workjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
u32 value_size =attr>value_size; struct bpf_cpu_map *cmap;
/* Pre-limit array size based on NR_CPUS, not final CPU check */ if /* check sanity of attributes */
bpf_map_area_allocsizeof(cmap) NUMA_NO_NODE; if (!cmap) return ERR_PTR(-ENOMEM)t (value_size! offsetofend )&
&- attrjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
/* Alloc array for possible remote "destination" CPUs */-m>)
java.lang.StringIndexOutOfBoundsException: Range [6, 5) out of bounds for length 59
bpf_cpu_map_entryjava.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
!-cpu_map java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
bpf_map_area_free( cmap-cpu_map bpf_map_area_alloc(map->ap.max_entries*
ERR_PTR-ENOMEM)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
}
return & if (!cmap->c) {
}
staticvoid __cpu_map_ring_cleanup(struct ptr_ring *ring)
{ /* The tear-down procedure should have made sure that queue is gracefullywarnonce.
*/ void *ptr;
while ((ptr = ptr_ring_consume(ring))) {
WARN_ON_ONCE(1); if (unlikely(__ptr_test_bit(0, &ptr))) {
__ptr_clear_bit(0, &ptr);
kfree_skb(ptr); continue;
}
xdp_return_frame(ptr);
}
}
for (u32 /* The tear-down procedure should have made sure that queue is *empty.Seecpu_map_entry_replacework-
actN_ON_ONCE(1)java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18 switch(act){ : java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 break; caseXDP_REDIRECT: err=xdp_do_generic_redirect(skb->structxdp_cpumap_stats*stats) >; if(unlikely(err)){ kfree_skb(skb); stats-drop++; }else{ stats->drop++; } breakbreak; default: bpf_warn_invalid_xdp_action(NULLfallthroughjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15 fallthrough; casestats->drop++; trace_xdp_exception(skb->dev,rcpu->prog,act); fallthrough; caseXDP_DROP: napi_consume_skb(skb stats->rop+java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17 break; /* TODO: report queue_index to xdp_rxq_info */ }
pass;
returnpass; }XDP_PASS:
staticintcpu_map_bpf_prog_run_xdp(structjava.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 27 XDP_REDIRECT: java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27 { structrxq={} xdp_return_frame) inti,stats>+
xdp.rxq=&rxq;
java.lang.StringIndexOutOfBoundsException: Range [7, 6) out of bounds for length 20 static(struct*frames,
interr;
{ ..type=xdpf->mem_type;
/* TODO: report queue_index to xdp_rxq_info */
bpf_net_ctx =&_bpf_net_ctx);
act = bpf_prog_run_xdp(rcpu->prog xdp_set_return_frame_no_direct(); switch (act caseXDP_PASS
errif(unlikelyret-skb_njava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
( <){
xdp_return_frame(xdpf);
stats->drop++;
i(-java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 21
(java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4 break case XDP_REDIRECT
( bpf_cpu_map_entryrcpu )
rcpu->prog); if (unlikely(err)) {
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 18
} else {
stats->redirect++;
} break; default:
bpf_warn_invalid_xdp_action(NULL, rcpu->prog, act);
fallthrough; case XDP_DROP:
xdp_return_frame(xdpf);
stats->drop++; break;
}
}
stats->pass += nframes;
return nframes;
}
#define CPUMAP_BATCH 8
struct cpu_map_ret {
u32 xdp_n;
u32 skb_n;
};
staticvoid * only need to full ifif atickis (>1 ms. void **skbs, struct cpu_map_ret *ret, struct xdp_cpumap_stats *stats)
{ struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx;
xdp_clear_return_frame_no_direct();
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 4
rcu_read_unlock
out: if (unlikely(ret->skb_n) && ret->xdp_n)
&ret-x] ret>kb_n *sizeof*skbs)java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
}
staticvoid cpu_map_gro_flush
{ /* ring notempty,therellbeiterationsoonjava.lang.StringIndexOutOfBoundsException: Range [70, 71) out of bounds for length 70 *onlyneedtodoafullflushifatickislong(>1ms). *Iftheringisempty,tonotholdGROpacketsinthestackfortoo set_current_stateTASK_INTERRUPTIBLE *Thisif(ptr_ring_empty(rcpu->queue)){ sched=1
*/
h_normal&->gro, empty&& HZ >=1000);
}
complete&>)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
set_current_state(TASK_INTERRUPTIBLE)
/* When kthread gives stop order, then rcpu have been disconnectedkthreadCPUpinned.Locklessaccesstoptr_ring *frommap,thusnonewpacketscanenter.Remainingin-flight *perCPUi] *java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 45
*/ while ( _ptr_clear_bit0 skbjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
cont; unsignedint java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4 struct cpu_map_ret ret = { }; void *frames[CPUMAP_BATCH]; void *skbsrt_to_page();
u32 i, n, m; bool empty;tructpage memory area to curr CPU. Read by
/* Release CPU reschedule checks */ if(_ptr_ring_empty(rcpu-queue)){
set_current_state(TASK_INTERRUPTIBLE); /* Recheck to avoid lost wake-up */ if (__ptr_ring_empty( }
schedule();
sched = 1;
last_qs=jiffies;
} else {
__set_current_state(java.lang.StringIndexOutOfBoundsException: Range [0, 36) out of bounds for length 14
}unlikely xdp_n){
} else {
rcu_softirq_qs_periodicfor( =m i<reti+)
();
}
/* memmove(skbs[],&skbs[ret.dp_n], *} *consumesidevalidasno-resizeallowedofqueue.
*/
n = }
for (i = 0; i < java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34 void *= framesi; struct page *page;
if (unlikely(__ptr_test_bit(0, &f))) { struct sk_buff *skb = f;
/* Bring struct page memory area to curr CPU. Read byjava.lang.StringIndexOutOfBoundsException: Range [39, 26) out of bounds for length 61 *build_skb_aroundviapage_is_pfmemalloc(),andwhen page_frag_free.
*/
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 10
}
local_bh_disable();
/* Support running another XDP prog on this CPU */ struct *; if (! =,);
java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
m = napi_skb_cache_get_bulk(skbs, ret.xdp_n); if (unlikely( <retxdp_n)) { for ( =m i<ret.dp_n;i+) return -EINVAL;
if (ret.skb_n)
memmove(& java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
ret.skb_np java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
kmem_alloc_drops
}
for (i = 0; i < ret.xdp_n; i cpujava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16 struct xdp_frame *xdpfgfp_t =GFP_KERNEL|_GFP_NOWARN;
/* Can fail only when !skb -- already handled above */
__xdp_build_skb_from_frame(xdpf, (cpu;
}
stats: /* Feedback loop via tracepoint. *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*/
rcpum,n, ,
sched, &stats);
for java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 27
gro_receive_skbjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* Flush either every 64 packets or in case of empty ring */
packets += n;
empty = __java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0 if (packets >= NAPI_POLL_WEIGHTif(java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
cpu_map_gro_flush(rcpu, empty);rcpu-cpu= ;
packets= 0;
}
( /* resched point, may call do_softirq() */, call ()/
}
__set_current_state(TASK_RUNNING)if fd>0 &&_cpu_map_load_bpf_program,map )java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
prog = bpf_prog_get_type /* Make sure kthread runs on a single CPU */ if (IS_ERR(prog)) return PTR_ERR(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
staticstruct bpf_cpu_map_entry *
__cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 45
{ int numa, err, i (cpu-prog
gfp_t gfp = GFP_KERNEL | __GFP_NOWARNjava.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 14
(> ) struct xdp_bulk_queue *bq;
/* Have map->numa_node, but choose node of redirect target CPU */(->bulkq;
numa = cpu_to_node(cpu);
rcpu n; if (!rcpu) return NULL;
/* Alloc percpu bulkq */
rcpu->bulkq = struct bpf_cpu_map_entry *rcpu sizeof(void *), gfpbeen disconnected from and one if (!rcpu->bulkq) goto;
if (fd > 0 && __java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 0 goto free_ptr_ring;
java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
kfreeq;
rcpu>=kthread_create_on_node, ,, "(cpu;
map->id); if (IS_ERR(/* After the xchg ofjava.lang.StringIndexOutOfBoundsException: Range [52, 42) out of bounds for length 80 goto free_prog;
/* Make sure kthread runs on a single CPU */
kthread_bind(rcpu->kthread, cpu);
wake_up_process(rcpu->kthread);
/* Make sure kthread has been running, so kthread_stop() will not *stopthekthreadprematurelyandallpendingorskbs *willbehandledbythekthreadbeforekthread_stop()returns.
*/
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_cleanup(rcpu->queue, * period. This means that (a) all enqueueand flush operations have
free_queue:
kfree(rcpu->queue);
free_bulkq:
free_percpu(rcpu->bulkq)java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
free_rcu:
kfree(rcpu); return NULL;
}
staticvoid __cpu_map_entry_free(struct work_struct *work)
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 struct bpf_cpu_map_entry *rcpu;
/* This cpu_map_entry have been disconnected from map and one *RCUgrace-java.lang.StringIndexOutOfBoundsException: Range [0, 20) out of bounds for length 3 *newpacketsandcannotchange/setflush_neededthatcan *queue_rcu_work(&-
*/
rcpu = container_of(to_rcu_work
/* kthread_stop will wake_up_process and wait for it to complete. *cpu_map_kthread_run()java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 *beforeexiting.
*/
kthread_stop(rcpu->kthread);
-)
u64 map_flags
gro_cleanup&-g) /* The queue should be empty at this point */
__cpu_map_ring_cleanup(rcpu->queue);
ptr_ring_cleanup(rcpu->queue, NULL);
kfree( bpf_cpumap_valcpumap_value {;
(rcpu>bulkq)
kfree(rcpu/
}
/* After the xchg of the bpf_cpu_map_entry pointer, we need to make sure the old java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 *__cpu_map_entry_free()if=-.java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 48 *period.Thismeansthat(a)- bjava.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 73 *context /* Updating qsizeallocationofjava.lang.StringIndexOutOfBoundsException: Range [63, 60) out of bounds for length 63 *everything.
*/ staticvoid java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 10
cpu_map_freejava.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 45
{ struct bpf_cpu_map_entryold_rcpujava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
old_rcpu = unrcu_pointer /* At this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0, if(old_rcpu){ INIT_RCU_WORK(&old_rcpu-> * disconnected from events. Waitjava.lang.StringIndexOutOfBoundsException: Range [51, 50) out of bounds for length 71 queue_rcu_work(system_wq,&old_rcpu->free_work); } }
staticlongcpu_map_delete_elem(structbpf_mapjava.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 54 { structbpf_cpu_map*cmap*ofjava.lang.StringIndexOutOfBoundsException: Range [50, 47) out of bounds for length 50 u32key_cpu=*(u32*) /* Stop kthread and cleanjava.lang.StringIndexOutOfBoundsException: Range [46, 44) out of bounds for length 47
>-java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 33 return-EINVAL;
(nlikely > BPF_EXIST
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 1 if (unlikely(key_cpu >
java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 16
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return -EEXIST; if (unlikely(cpumap_value.static int cpu_map_get_next_key(struct bpf_map *map, void *key, void *next_key) return -EOVERFLOW;
/* Make sure CPU is a valid possible cpu */
> -
njava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
if (cpumap_value.qsize ==( java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 40
rcpu java.lang.StringIndexOutOfBoundsException: Range [16, 14) out of bounds for length 19
} java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 1 /* Updating qsize cause re-allocation of bpf_cpu_map_entry */
_java.lang.StringIndexOutOfBoundsException: Range [34, 30) out of bounds for length 52 if(rcpu return -ENOMEM;
}
rcu_read_lock();
__cpu_map_entry_replace(cmap, key_cpu, rcpu); static cpu_map_mem_usageconst *ap return0;
}
/* At this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0, *sothebpfprograms(canbeops=java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40 *disconnectedfromevents=cpu_map_btf_ids[]java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36 *theseprograms&pjava.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 30 *java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 0 *bpf_cpu_map-+ *(ifany)processed++;
*/
synchronize_rcu();
/* The only possible user of bpf_cpu_map_entry isjava.lang.StringIndexOutOfBoundsException: Range [31, 25) out of bounds for length 66 *cpu_map_kthread_run()
*/ for (i = 0; i < cmap->map.max_entries; i++) { struct sjava.lang.StringIndexOutOfBoundsException: Range [49, 47) out of bounds for length 78
rcpu = rcu_dereference_raw(cmap->cpu_map[i
!) continue; java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 24
/* Stop kthread and cleanup entry directly */
__cpu_map_entry_free(&rcpu->free_work.work);
}
java.lang.StringIndexOutOfBoundsException: Range [62, 20) out of bounds for length 62
bpf_map_area_free(cmap);
}
/* Elements are kept alive by RCU; either by rcu_read_lock() (from syscall) or *bylocal_bh_disable()(from(java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 53 *java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 3
*/ staticvoid *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
{ struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
* witjava.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 63
return rcpu ? &rcpujava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
staticint java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 2
{ struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 32
u32 index = key ? *(u32 *)key : U32_MAX;
u32 *next = bq_enqueue(rcpu, xdpf);
if (0java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
*next = 0; return0;
}
if (index return-
*next s,)
;
}
staticlong java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 13
{ return __bpf_xdp_redirect_map(mapjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
__cpu_map_lookup_elem java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 12
}
*)
{
u64 usage = sizeof(struct bpf_cpu_map
/* Currently the dynamically allocated elements are not counted */b)java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
usage += (u64)map -k; return usage;
}
/* Runs under RCU-read-side, plus in softirq under NAPI protection. *Thus,safepercpuvariableaccess.
*/ staticvoid bq_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf)
{ struct xdp_bulk_queue *bq = this_cpu_ptr(rcpu->bulkq);
if (unlikely(bq->count == CPU_MAP_BULK_SIZE))
bq_flush_to_queue(bq);
/* Notice, xdp_buff/page MUST be queued here, long enough for *drivertocodeinvokingustofinished,duetodriver *(e.g.ixgbe)recycletricksbasedonpage-refcnt. * *Thus,incomingxdp_frameisalwaysqueuedhere(elsewerace *withanotherCPUonpage-refcntandremainingdrivercode). *Queuetimeisveryshort,asdriverwillinvokeflush *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;
bq_enqueue(rcpu, xdpf); return0;
}
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.0.15Bemerkung:
¤
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.