History

cpumap: Formalize map value as a named struct

As it has been already done for devmap, introduce 'struct bpf_cpumap_val' to formalize the expected values that can be passed in for a CPUMAP. Update cpumap code to use the struct.

Lorenzo Bianconi committed 6 years ago

Commit 644bfe51 parent a4e76f13 files · +33 −13Browse files

Unified · Split

3 files
  1. include/uapi/linux/bpf.h +9 −0
  2. kernel/bpf/cpumap.c +15 −13
  3. tools/include/uapi/linux/bpf.h +9 −0
include/uapi/linux/bpf.h+9−0
@@ -3849,6 +3849,15 @@ struct bpf_devmap_val { · 3848 unmodified lines
3849 } bpf_prog;3849 } bpf_prog;
3850};3850};
3851 3851
3852/* CPUMAP map-value layout
3853 *
3854 * The struct data-layout of map-value is a configuration interface.
3855 * New members can only be added to the end of this structure.
3856 */
3857struct bpf_cpumap_val {
3858 __u32 qsize; /* queue size to remote target CPU */
3859};
3860
3852enum sk_action {3861enum sk_action {
3853 SK_DROP = 0,3862 SK_DROP = 0,
3854 SK_PASS,3863 SK_PASS,
kernel/bpf/cpumap.c+15−13
@@ -52,7 +52,6 @@ struct xdp_bulk_queue { · 51 unmodified lines
52struct bpf_cpu_map_entry {52struct bpf_cpu_map_entry {
53 u32 cpu; /* kthread CPU and map index */53 u32 cpu; /* kthread CPU and map index */
54 int map_id; /* Back reference to map */54 int map_id; /* Back reference to map */
55 u32 qsize; /* Queue size placeholder for map lookup */
56 55
57 /* XDP can run multiple RX-ring queues, need __percpu enqueue store */56 /* XDP can run multiple RX-ring queues, need __percpu enqueue store */
58 struct xdp_bulk_queue __percpu *bulkq;57 struct xdp_bulk_queue __percpu *bulkq;
@@ -62,10 +61,13 @@ struct bpf_cpu_map_entry { · 3 unmodified lines
62 /* Queue with potential multi-producers, and single-consumer kthread */61 /* Queue with potential multi-producers, and single-consumer kthread */
63 struct ptr_ring *queue;62 struct ptr_ring *queue;
64 struct task_struct *kthread;63 struct task_struct *kthread;
65 struct work_struct kthread_stop_wq;64
65 struct bpf_cpumap_val value;
66 66
67 atomic_t refcnt; /* Control when this struct can be free'ed */67 atomic_t refcnt; /* Control when this struct can be free'ed */
68 struct rcu_head rcu;68 struct rcu_head rcu;
69
70 struct work_struct kthread_stop_wq;
69};71};
70 72
71struct bpf_cpu_map {73struct bpf_cpu_map {
@@ -307,8 +309,8 @@ static int cpu_map_kthread_run(void *data) · 235 unmodified lines
307 return 0;309 return 0;
308}310}
309 311
310static struct bpf_cpu_map_entry *__cpu_map_entry_alloc(u32 qsize, u32 cpu,312static struct bpf_cpu_map_entry *
311 int map_id)313__cpu_map_entry_alloc(struct bpf_cpumap_val *value, u32 cpu, int map_id)
312{314{
313 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;315 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
314 struct bpf_cpu_map_entry *rcpu;316 struct bpf_cpu_map_entry *rcpu;
@@ -338,13 +340,13 @@ static struct bpf_cpu_map_entry *__cpu_map_entry_alloc(u32 qsize, u32 cpu, · 23 unmodified lines
338 if (!rcpu->queue)340 if (!rcpu->queue)
339 goto free_bulkq;341 goto free_bulkq;
340 342
341 err = ptr_ring_init(rcpu->queue, qsize, gfp);343 err = ptr_ring_init(rcpu->queue, value->qsize, gfp);
342 if (err)344 if (err)
343 goto free_queue;345 goto free_queue;
344 346
345 rcpu->cpu = cpu;347 rcpu->cpu = cpu;
346 rcpu->map_id = map_id;348 rcpu->map_id = map_id;
347 rcpu->qsize = qsize;349 rcpu->value.qsize = value->qsize;
348 350
349 /* Setup kthread */351 /* Setup kthread */
350 rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa,352 rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa,
@@ -437,12 +439,12 @@ static int cpu_map_update_elem(struct bpf_map *map, void *key, void *value, · 86 unmodified lines
437 u64 map_flags)439 u64 map_flags)
438{440{
439 struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);441 struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
442 struct bpf_cpumap_val cpumap_value = {};
440 struct bpf_cpu_map_entry *rcpu;443 struct bpf_cpu_map_entry *rcpu;
441
442 /* Array index key correspond to CPU number */444 /* Array index key correspond to CPU number */
443 u32 key_cpu = *(u32 *)key;445 u32 key_cpu = *(u32 *)key;
444 /* Value is the queue size */446
445 u32 qsize = *(u32 *)value;447 memcpy(&cpumap_value, value, map->value_size);
446 448
447 if (unlikely(map_flags > BPF_EXIST))449 if (unlikely(map_flags > BPF_EXIST))
448 return -EINVAL;450 return -EINVAL;
@@ -450,18 +452,18 @@ static int cpu_map_update_elem(struct bpf_map *map, void *key, void *value, · 1 unmodified line
450 return -E2BIG;452 return -E2BIG;
451 if (unlikely(map_flags == BPF_NOEXIST))453 if (unlikely(map_flags == BPF_NOEXIST))
452 return -EEXIST;454 return -EEXIST;
453 if (unlikely(qsize > 16384)) /* sanity limit on qsize */455 if (unlikely(cpumap_value.qsize > 16384)) /* sanity limit on qsize */
454 return -EOVERFLOW;456 return -EOVERFLOW;
455 457
456 /* Make sure CPU is a valid possible cpu */458 /* Make sure CPU is a valid possible cpu */
457 if (key_cpu >= nr_cpumask_bits || !cpu_possible(key_cpu))459 if (key_cpu >= nr_cpumask_bits || !cpu_possible(key_cpu))
458 return -ENODEV;460 return -ENODEV;
459 461
460 if (qsize == 0) {462 if (cpumap_value.qsize == 0) {
461 rcpu = NULL; /* Same as deleting */463 rcpu = NULL; /* Same as deleting */
462 } else {464 } else {
463 /* Updating qsize cause re-allocation of bpf_cpu_map_entry */465 /* Updating qsize cause re-allocation of bpf_cpu_map_entry */
464 rcpu = __cpu_map_entry_alloc(qsize, key_cpu, map->id);466 rcpu = __cpu_map_entry_alloc(&cpumap_value, key_cpu, map->id);
465 if (!rcpu)467 if (!rcpu)
466 return -ENOMEM;468 return -ENOMEM;
467 rcpu->cmap = cmap;469 rcpu->cmap = cmap;
@@ -523,7 +525,7 @@ static void *cpu_map_lookup_elem(struct bpf_map *map, void *key) · 55 unmodified lines
523 struct bpf_cpu_map_entry *rcpu =525 struct bpf_cpu_map_entry *rcpu =
524 __cpu_map_lookup_elem(map, *(u32 *)key);526 __cpu_map_lookup_elem(map, *(u32 *)key);
525 527
526 return rcpu ? &rcpu->qsize : NULL;528 return rcpu ? &rcpu->value : NULL;
527}529}
528 530
529static int cpu_map_get_next_key(struct bpf_map *map, void *key, void *next_key)531static int cpu_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
tools/include/uapi/linux/bpf.h+9−0
@@ -3849,6 +3849,15 @@ struct bpf_devmap_val { · 3848 unmodified lines
3849 } bpf_prog;3849 } bpf_prog;
3850};3850};
3851 3851
3852/* CPUMAP map-value layout
3853 *
3854 * The struct data-layout of map-value is a configuration interface.
3855 * New members can only be added to the end of this structure.
3856 */
3857struct bpf_cpumap_val {
3858 __u32 qsize; /* queue size to remote target CPU */
3859};
3860
3852enum sk_action {3861enum sk_action {
3853 SK_DROP = 0,3862 SK_DROP = 0,
3854 SK_PASS,3863 SK_PASS,