LCOV - code coverage report
Current view: top level - kernel/bpf - cpumap.c (source / functions) Hit Total Coverage
Test: gcov_data_raspi2_qemu_modules_combined.info Lines: 0 209 0.0 %
Date: 2020-09-30 20:25:01 Functions: 0 19 0.0 %
Branches: 0 126 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-only
       2                 :            : /* bpf/cpumap.c
       3                 :            :  *
       4                 :            :  * Copyright (c) 2017 Jesper Dangaard Brouer, Red Hat Inc.
       5                 :            :  */
       6                 :            : 
       7                 :            : /* The 'cpumap' is primarily used as a backend map for XDP BPF helper
       8                 :            :  * call bpf_redirect_map() and XDP_REDIRECT action, like 'devmap'.
       9                 :            :  *
      10                 :            :  * Unlike devmap which redirects XDP frames out another NIC device,
      11                 :            :  * this map type redirects raw XDP frames to another CPU.  The remote
      12                 :            :  * CPU will do SKB-allocation and call the normal network stack.
      13                 :            :  *
      14                 :            :  * This is a scalability and isolation mechanism, that allow
      15                 :            :  * separating the early driver network XDP layer, from the rest of the
      16                 :            :  * netstack, and assigning dedicated CPUs for this stage.  This
      17                 :            :  * basically allows for 10G wirespeed pre-filtering via bpf.
      18                 :            :  */
      19                 :            : #include <linux/bpf.h>
      20                 :            : #include <linux/filter.h>
      21                 :            : #include <linux/ptr_ring.h>
      22                 :            : #include <net/xdp.h>
      23                 :            : 
      24                 :            : #include <linux/sched.h>
      25                 :            : #include <linux/workqueue.h>
      26                 :            : #include <linux/kthread.h>
      27                 :            : #include <linux/capability.h>
      28                 :            : #include <trace/events/xdp.h>
      29                 :            : 
      30                 :            : #include <linux/netdevice.h>   /* netif_receive_skb_core */
      31                 :            : #include <linux/etherdevice.h> /* eth_type_trans */
      32                 :            : 
      33                 :            : /* General idea: XDP packets getting XDP redirected to another CPU,
      34                 :            :  * will maximum be stored/queued for one driver ->poll() call.  It is
      35                 :            :  * guaranteed that queueing the frame and the flush operation happen on
      36                 :            :  * same CPU.  Thus, cpu_map_flush operation can deduct via this_cpu_ptr()
      37                 :            :  * which queue in bpf_cpu_map_entry contains packets.
      38                 :            :  */
      39                 :            : 
      40                 :            : #define CPU_MAP_BULK_SIZE 8  /* 8 == one cacheline on 64-bit archs */
      41                 :            : struct bpf_cpu_map_entry;
      42                 :            : struct bpf_cpu_map;
      43                 :            : 
      44                 :            : struct xdp_bulk_queue {
      45                 :            :         void *q[CPU_MAP_BULK_SIZE];
      46                 :            :         struct list_head flush_node;
      47                 :            :         struct bpf_cpu_map_entry *obj;
      48                 :            :         unsigned int count;
      49                 :            : };
      50                 :            : 
      51                 :            : /* Struct for every remote "destination" CPU in map */
      52                 :            : struct bpf_cpu_map_entry {
      53                 :            :         u32 cpu;    /* kthread CPU and map index */
      54                 :            :         int map_id; /* Back reference to map */
      55                 :            :         u32 qsize;  /* Queue size placeholder for map lookup */
      56                 :            : 
      57                 :            :         /* XDP can run multiple RX-ring queues, need __percpu enqueue store */
      58                 :            :         struct xdp_bulk_queue __percpu *bulkq;
      59                 :            : 
      60                 :            :         struct bpf_cpu_map *cmap;
      61                 :            : 
      62                 :            :         /* Queue with potential multi-producers, and single-consumer kthread */
      63                 :            :         struct ptr_ring *queue;
      64                 :            :         struct task_struct *kthread;
      65                 :            :         struct work_struct kthread_stop_wq;
      66                 :            : 
      67                 :            :         atomic_t refcnt; /* Control when this struct can be free'ed */
      68                 :            :         struct rcu_head rcu;
      69                 :            : };
      70                 :            : 
      71                 :            : struct bpf_cpu_map {
      72                 :            :         struct bpf_map map;
      73                 :            :         /* Below members specific for map type */
      74                 :            :         struct bpf_cpu_map_entry **cpu_map;
      75                 :            :         struct list_head __percpu *flush_list;
      76                 :            : };
      77                 :            : 
      78                 :            : static int bq_flush_to_queue(struct xdp_bulk_queue *bq, bool in_napi_ctx);
      79                 :            : 
      80                 :          0 : static struct bpf_map *cpu_map_alloc(union bpf_attr *attr)
      81                 :            : {
      82                 :            :         struct bpf_cpu_map *cmap;
      83                 :            :         int err = -ENOMEM;
      84                 :            :         int ret, cpu;
      85                 :            :         u64 cost;
      86                 :            : 
      87         [ #  # ]:          0 :         if (!capable(CAP_SYS_ADMIN))
      88                 :            :                 return ERR_PTR(-EPERM);
      89                 :            : 
      90                 :            :         /* check sanity of attributes */
      91   [ #  #  #  #  :          0 :         if (attr->max_entries == 0 || attr->key_size != 4 ||
                   #  # ]
      92         [ #  # ]:          0 :             attr->value_size != 4 || attr->map_flags & ~BPF_F_NUMA_NODE)
      93                 :            :                 return ERR_PTR(-EINVAL);
      94                 :            : 
      95                 :          0 :         cmap = kzalloc(sizeof(*cmap), GFP_USER);
      96         [ #  # ]:          0 :         if (!cmap)
      97                 :            :                 return ERR_PTR(-ENOMEM);
      98                 :            : 
      99                 :          0 :         bpf_map_init_from_attr(&cmap->map, attr);
     100                 :            : 
     101                 :            :         /* Pre-limit array size based on NR_CPUS, not final CPU check */
     102         [ #  # ]:          0 :         if (cmap->map.max_entries > NR_CPUS) {
     103                 :            :                 err = -E2BIG;
     104                 :            :                 goto free_cmap;
     105                 :            :         }
     106                 :            : 
     107                 :            :         /* make sure page count doesn't overflow */
     108                 :          0 :         cost = (u64) cmap->map.max_entries * sizeof(struct bpf_cpu_map_entry *);
     109                 :          0 :         cost += sizeof(struct list_head) * num_possible_cpus();
     110                 :            : 
     111                 :            :         /* Notice returns -EPERM on if map size is larger than memlock limit */
     112                 :          0 :         ret = bpf_map_charge_init(&cmap->map.memory, cost);
     113         [ #  # ]:          0 :         if (ret) {
     114                 :            :                 err = ret;
     115                 :            :                 goto free_cmap;
     116                 :            :         }
     117                 :            : 
     118                 :          0 :         cmap->flush_list = alloc_percpu(struct list_head);
     119         [ #  # ]:          0 :         if (!cmap->flush_list)
     120                 :            :                 goto free_charge;
     121                 :            : 
     122         [ #  # ]:          0 :         for_each_possible_cpu(cpu)
     123                 :          0 :                 INIT_LIST_HEAD(per_cpu_ptr(cmap->flush_list, cpu));
     124                 :            : 
     125                 :            :         /* Alloc array for possible remote "destination" CPUs */
     126                 :          0 :         cmap->cpu_map = bpf_map_area_alloc(cmap->map.max_entries *
     127                 :            :                                            sizeof(struct bpf_cpu_map_entry *),
     128                 :            :                                            cmap->map.numa_node);
     129         [ #  # ]:          0 :         if (!cmap->cpu_map)
     130                 :            :                 goto free_percpu;
     131                 :            : 
     132                 :            :         return &cmap->map;
     133                 :            : free_percpu:
     134                 :          0 :         free_percpu(cmap->flush_list);
     135                 :            : free_charge:
     136                 :          0 :         bpf_map_charge_finish(&cmap->map.memory);
     137                 :            : free_cmap:
     138                 :          0 :         kfree(cmap);
     139                 :          0 :         return ERR_PTR(err);
     140                 :            : }
     141                 :            : 
     142                 :            : static void get_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)
     143                 :            : {
     144                 :          0 :         atomic_inc(&rcpu->refcnt);
     145                 :            : }
     146                 :            : 
     147                 :            : /* called from workqueue, to workaround syscall using preempt_disable */
     148                 :          0 : static void cpu_map_kthread_stop(struct work_struct *work)
     149                 :            : {
     150                 :            :         struct bpf_cpu_map_entry *rcpu;
     151                 :            : 
     152                 :            :         rcpu = container_of(work, struct bpf_cpu_map_entry, kthread_stop_wq);
     153                 :            : 
     154                 :            :         /* Wait for flush in __cpu_map_entry_free(), via full RCU barrier,
     155                 :            :          * as it waits until all in-flight call_rcu() callbacks complete.
     156                 :            :          */
     157                 :          0 :         rcu_barrier();
     158                 :            : 
     159                 :            :         /* kthread_stop will wake_up_process and wait for it to complete */
     160                 :          0 :         kthread_stop(rcpu->kthread);
     161                 :          0 : }
     162                 :            : 
     163                 :          0 : static struct sk_buff *cpu_map_build_skb(struct bpf_cpu_map_entry *rcpu,
     164                 :            :                                          struct xdp_frame *xdpf,
     165                 :            :                                          struct sk_buff *skb)
     166                 :            : {
     167                 :            :         unsigned int hard_start_headroom;
     168                 :            :         unsigned int frame_size;
     169                 :            :         void *pkt_data_start;
     170                 :            : 
     171                 :            :         /* Part of headroom was reserved to xdpf */
     172                 :          0 :         hard_start_headroom = sizeof(struct xdp_frame) +  xdpf->headroom;
     173                 :            : 
     174                 :            :         /* build_skb need to place skb_shared_info after SKB end, and
     175                 :            :          * also want to know the memory "truesize".  Thus, need to
     176                 :            :          * know the memory frame size backing xdp_buff.
     177                 :            :          *
     178                 :            :          * XDP was designed to have PAGE_SIZE frames, but this
     179                 :            :          * assumption is not longer true with ixgbe and i40e.  It
     180                 :            :          * would be preferred to set frame_size to 2048 or 4096
     181                 :            :          * depending on the driver.
     182                 :            :          *   frame_size = 2048;
     183                 :            :          *   frame_len  = frame_size - sizeof(*xdp_frame);
     184                 :            :          *
     185                 :            :          * Instead, with info avail, skb_shared_info in placed after
     186                 :            :          * packet len.  This, unfortunately fakes the truesize.
     187                 :            :          * Another disadvantage of this approach, the skb_shared_info
     188                 :            :          * is not at a fixed memory location, with mixed length
     189                 :            :          * packets, which is bad for cache-line hotness.
     190                 :            :          */
     191                 :          0 :         frame_size = SKB_DATA_ALIGN(xdpf->len + hard_start_headroom) +
     192                 :            :                 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
     193                 :            : 
     194                 :          0 :         pkt_data_start = xdpf->data - hard_start_headroom;
     195                 :          0 :         skb = build_skb_around(skb, pkt_data_start, frame_size);
     196         [ #  # ]:          0 :         if (unlikely(!skb))
     197                 :            :                 return NULL;
     198                 :            : 
     199                 :            :         skb_reserve(skb, hard_start_headroom);
     200                 :          0 :         __skb_put(skb, xdpf->len);
     201         [ #  # ]:          0 :         if (xdpf->metasize)
     202                 :          0 :                 skb_metadata_set(skb, xdpf->metasize);
     203                 :            : 
     204                 :            :         /* Essential SKB info: protocol and skb->dev */
     205                 :          0 :         skb->protocol = eth_type_trans(skb, xdpf->dev_rx);
     206                 :            : 
     207                 :            :         /* Optional SKB info, currently missing:
     208                 :            :          * - HW checksum info           (skb->ip_summed)
     209                 :            :          * - HW RX hash                 (skb_set_hash)
     210                 :            :          * - RX ring dev queue index    (skb_record_rx_queue)
     211                 :            :          */
     212                 :            : 
     213                 :            :         /* Until page_pool get SKB return path, release DMA here */
     214                 :            :         xdp_release_frame(xdpf);
     215                 :            : 
     216                 :            :         /* Allow SKB to reuse area used by xdp_frame */
     217                 :            :         xdp_scrub_frame(xdpf);
     218                 :            : 
     219                 :          0 :         return skb;
     220                 :            : }
     221                 :            : 
     222                 :          0 : static void __cpu_map_ring_cleanup(struct ptr_ring *ring)
     223                 :            : {
     224                 :            :         /* The tear-down procedure should have made sure that queue is
     225                 :            :          * empty.  See __cpu_map_entry_replace() and work-queue
     226                 :            :          * invoked cpu_map_kthread_stop(). Catch any broken behaviour
     227                 :            :          * gracefully and warn once.
     228                 :            :          */
     229                 :            :         struct xdp_frame *xdpf;
     230                 :            : 
     231         [ #  # ]:          0 :         while ((xdpf = ptr_ring_consume(ring)))
     232   [ #  #  #  #  :          0 :                 if (WARN_ON_ONCE(xdpf))
                   #  # ]
     233                 :          0 :                         xdp_return_frame(xdpf);
     234                 :          0 : }
     235                 :            : 
     236                 :          0 : static void put_cpu_map_entry(struct bpf_cpu_map_entry *rcpu)
     237                 :            : {
     238         [ #  # ]:          0 :         if (atomic_dec_and_test(&rcpu->refcnt)) {
     239                 :            :                 /* The queue should be empty at this point */
     240                 :          0 :                 __cpu_map_ring_cleanup(rcpu->queue);
     241                 :          0 :                 ptr_ring_cleanup(rcpu->queue, NULL);
     242                 :          0 :                 kfree(rcpu->queue);
     243                 :          0 :                 kfree(rcpu);
     244                 :            :         }
     245                 :          0 : }
     246                 :            : 
     247                 :            : #define CPUMAP_BATCH 8
     248                 :            : 
     249                 :          0 : static int cpu_map_kthread_run(void *data)
     250                 :            : {
     251                 :            :         struct bpf_cpu_map_entry *rcpu = data;
     252                 :            : 
     253                 :          0 :         set_current_state(TASK_INTERRUPTIBLE);
     254                 :            : 
     255                 :            :         /* When kthread gives stop order, then rcpu have been disconnected
     256                 :            :          * from map, thus no new packets can enter. Remaining in-flight
     257                 :            :          * per CPU stored packets are flushed to this queue.  Wait honoring
     258                 :            :          * kthread_stop signal until queue is empty.
     259                 :            :          */
     260   [ #  #  #  # ]:          0 :         while (!kthread_should_stop() || !__ptr_ring_empty(rcpu->queue)) {
     261                 :            :                 unsigned int drops = 0, sched = 0;
     262                 :            :                 void *frames[CPUMAP_BATCH];
     263                 :            :                 void *skbs[CPUMAP_BATCH];
     264                 :            :                 gfp_t gfp = __GFP_ZERO | GFP_ATOMIC;
     265                 :            :                 int i, n, m;
     266                 :            : 
     267                 :            :                 /* Release CPU reschedule checks */
     268         [ #  # ]:          0 :                 if (__ptr_ring_empty(rcpu->queue)) {
     269                 :          0 :                         set_current_state(TASK_INTERRUPTIBLE);
     270                 :            :                         /* Recheck to avoid lost wake-up */
     271         [ #  # ]:          0 :                         if (__ptr_ring_empty(rcpu->queue)) {
     272                 :          0 :                                 schedule();
     273                 :            :                                 sched = 1;
     274                 :            :                         } else {
     275                 :          0 :                                 __set_current_state(TASK_RUNNING);
     276                 :            :                         }
     277                 :            :                 } else {
     278                 :          0 :                         sched = cond_resched();
     279                 :            :                 }
     280                 :            : 
     281                 :            :                 /*
     282                 :            :                  * The bpf_cpu_map_entry is single consumer, with this
     283                 :            :                  * kthread CPU pinned. Lockless access to ptr_ring
     284                 :            :                  * consume side valid as no-resize allowed of queue.
     285                 :            :                  */
     286                 :          0 :                 n = ptr_ring_consume_batched(rcpu->queue, frames, CPUMAP_BATCH);
     287                 :            : 
     288         [ #  # ]:          0 :                 for (i = 0; i < n; i++) {
     289                 :          0 :                         void *f = frames[i];
     290                 :          0 :                         struct page *page = virt_to_page(f);
     291                 :            : 
     292                 :            :                         /* Bring struct page memory area to curr CPU. Read by
     293                 :            :                          * build_skb_around via page_is_pfmemalloc(), and when
     294                 :            :                          * freed written by page_frag_free call.
     295                 :            :                          */
     296                 :            :                         prefetchw(page);
     297                 :            :                 }
     298                 :            : 
     299                 :          0 :                 m = kmem_cache_alloc_bulk(skbuff_head_cache, gfp, n, skbs);
     300         [ #  # ]:          0 :                 if (unlikely(m == 0)) {
     301         [ #  # ]:          0 :                         for (i = 0; i < n; i++)
     302                 :          0 :                                 skbs[i] = NULL; /* effect: xdp_return_frame */
     303                 :            :                         drops = n;
     304                 :            :                 }
     305                 :            : 
     306                 :            :                 local_bh_disable();
     307         [ #  # ]:          0 :                 for (i = 0; i < n; i++) {
     308                 :          0 :                         struct xdp_frame *xdpf = frames[i];
     309                 :          0 :                         struct sk_buff *skb = skbs[i];
     310                 :            :                         int ret;
     311                 :            : 
     312                 :          0 :                         skb = cpu_map_build_skb(rcpu, xdpf, skb);
     313         [ #  # ]:          0 :                         if (!skb) {
     314                 :          0 :                                 xdp_return_frame(xdpf);
     315                 :          0 :                                 continue;
     316                 :            :                         }
     317                 :            : 
     318                 :            :                         /* Inject into network stack */
     319                 :          0 :                         ret = netif_receive_skb_core(skb);
     320         [ #  # ]:          0 :                         if (ret == NET_RX_DROP)
     321                 :          0 :                                 drops++;
     322                 :            :                 }
     323                 :            :                 /* Feedback loop via tracepoint */
     324                 :          0 :                 trace_xdp_cpumap_kthread(rcpu->map_id, n, drops, sched);
     325                 :            : 
     326                 :            :                 local_bh_enable(); /* resched point, may call do_softirq() */
     327                 :            :         }
     328                 :          0 :         __set_current_state(TASK_RUNNING);
     329                 :            : 
     330                 :          0 :         put_cpu_map_entry(rcpu);
     331                 :          0 :         return 0;
     332                 :            : }
     333                 :            : 
     334                 :          0 : static struct bpf_cpu_map_entry *__cpu_map_entry_alloc(u32 qsize, u32 cpu,
     335                 :            :                                                        int map_id)
     336                 :            : {
     337                 :            :         gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
     338                 :            :         struct bpf_cpu_map_entry *rcpu;
     339                 :            :         struct xdp_bulk_queue *bq;
     340                 :            :         int numa, err, i;
     341                 :            : 
     342                 :            :         /* Have map->numa_node, but choose node of redirect target CPU */
     343                 :            :         numa = cpu_to_node(cpu);
     344                 :            : 
     345                 :          0 :         rcpu = kzalloc_node(sizeof(*rcpu), gfp, numa);
     346         [ #  # ]:          0 :         if (!rcpu)
     347                 :            :                 return NULL;
     348                 :            : 
     349                 :            :         /* Alloc percpu bulkq */
     350                 :          0 :         rcpu->bulkq = __alloc_percpu_gfp(sizeof(*rcpu->bulkq),
     351                 :            :                                          sizeof(void *), gfp);
     352         [ #  # ]:          0 :         if (!rcpu->bulkq)
     353                 :            :                 goto free_rcu;
     354                 :            : 
     355         [ #  # ]:          0 :         for_each_possible_cpu(i) {
     356                 :          0 :                 bq = per_cpu_ptr(rcpu->bulkq, i);
     357                 :          0 :                 bq->obj = rcpu;
     358                 :            :         }
     359                 :            : 
     360                 :            :         /* Alloc queue */
     361                 :          0 :         rcpu->queue = kzalloc_node(sizeof(*rcpu->queue), gfp, numa);
     362         [ #  # ]:          0 :         if (!rcpu->queue)
     363                 :            :                 goto free_bulkq;
     364                 :            : 
     365                 :          0 :         err = ptr_ring_init(rcpu->queue, qsize, gfp);
     366         [ #  # ]:          0 :         if (err)
     367                 :            :                 goto free_queue;
     368                 :            : 
     369                 :          0 :         rcpu->cpu    = cpu;
     370                 :          0 :         rcpu->map_id = map_id;
     371                 :          0 :         rcpu->qsize  = qsize;
     372                 :            : 
     373                 :            :         /* Setup kthread */
     374                 :          0 :         rcpu->kthread = kthread_create_on_node(cpu_map_kthread_run, rcpu, numa,
     375                 :            :                                                "cpumap/%d/map:%d", cpu, map_id);
     376         [ #  # ]:          0 :         if (IS_ERR(rcpu->kthread))
     377                 :            :                 goto free_ptr_ring;
     378                 :            : 
     379                 :            :         get_cpu_map_entry(rcpu); /* 1-refcnt for being in cmap->cpu_map[] */
     380                 :            :         get_cpu_map_entry(rcpu); /* 1-refcnt for kthread */
     381                 :            : 
     382                 :            :         /* Make sure kthread runs on a single CPU */
     383                 :          0 :         kthread_bind(rcpu->kthread, cpu);
     384                 :          0 :         wake_up_process(rcpu->kthread);
     385                 :            : 
     386                 :          0 :         return rcpu;
     387                 :            : 
     388                 :            : free_ptr_ring:
     389                 :          0 :         ptr_ring_cleanup(rcpu->queue, NULL);
     390                 :            : free_queue:
     391                 :          0 :         kfree(rcpu->queue);
     392                 :            : free_bulkq:
     393                 :          0 :         free_percpu(rcpu->bulkq);
     394                 :            : free_rcu:
     395                 :          0 :         kfree(rcpu);
     396                 :          0 :         return NULL;
     397                 :            : }
     398                 :            : 
     399                 :          0 : static void __cpu_map_entry_free(struct rcu_head *rcu)
     400                 :            : {
     401                 :            :         struct bpf_cpu_map_entry *rcpu;
     402                 :            :         int cpu;
     403                 :            : 
     404                 :            :         /* This cpu_map_entry have been disconnected from map and one
     405                 :            :          * RCU graze-period have elapsed.  Thus, XDP cannot queue any
     406                 :            :          * new packets and cannot change/set flush_needed that can
     407                 :            :          * find this entry.
     408                 :            :          */
     409                 :          0 :         rcpu = container_of(rcu, struct bpf_cpu_map_entry, rcu);
     410                 :            : 
     411                 :            :         /* Flush remaining packets in percpu bulkq */
     412         [ #  # ]:          0 :         for_each_online_cpu(cpu) {
     413                 :          0 :                 struct xdp_bulk_queue *bq = per_cpu_ptr(rcpu->bulkq, cpu);
     414                 :            : 
     415                 :            :                 /* No concurrent bq_enqueue can run at this point */
     416                 :          0 :                 bq_flush_to_queue(bq, false);
     417                 :            :         }
     418                 :          0 :         free_percpu(rcpu->bulkq);
     419                 :            :         /* Cannot kthread_stop() here, last put free rcpu resources */
     420                 :          0 :         put_cpu_map_entry(rcpu);
     421                 :          0 : }
     422                 :            : 
     423                 :            : /* After xchg pointer to bpf_cpu_map_entry, use the call_rcu() to
     424                 :            :  * ensure any driver rcu critical sections have completed, but this
     425                 :            :  * does not guarantee a flush has happened yet. Because driver side
     426                 :            :  * rcu_read_lock/unlock only protects the running XDP program.  The
     427                 :            :  * atomic xchg and NULL-ptr check in __cpu_map_flush() makes sure a
     428                 :            :  * pending flush op doesn't fail.
     429                 :            :  *
     430                 :            :  * The bpf_cpu_map_entry is still used by the kthread, and there can
     431                 :            :  * still be pending packets (in queue and percpu bulkq).  A refcnt
     432                 :            :  * makes sure to last user (kthread_stop vs. call_rcu) free memory
     433                 :            :  * resources.
     434                 :            :  *
     435                 :            :  * The rcu callback __cpu_map_entry_free flush remaining packets in
     436                 :            :  * percpu bulkq to queue.  Due to caller map_delete_elem() disable
     437                 :            :  * preemption, cannot call kthread_stop() to make sure queue is empty.
     438                 :            :  * Instead a work_queue is started for stopping kthread,
     439                 :            :  * cpu_map_kthread_stop, which waits for an RCU graze period before
     440                 :            :  * stopping kthread, emptying the queue.
     441                 :            :  */
     442                 :          0 : static void __cpu_map_entry_replace(struct bpf_cpu_map *cmap,
     443                 :            :                                     u32 key_cpu, struct bpf_cpu_map_entry *rcpu)
     444                 :            : {
     445                 :            :         struct bpf_cpu_map_entry *old_rcpu;
     446                 :            : 
     447                 :          0 :         old_rcpu = xchg(&cmap->cpu_map[key_cpu], rcpu);
     448         [ #  # ]:          0 :         if (old_rcpu) {
     449                 :          0 :                 call_rcu(&old_rcpu->rcu, __cpu_map_entry_free);
     450                 :          0 :                 INIT_WORK(&old_rcpu->kthread_stop_wq, cpu_map_kthread_stop);
     451                 :          0 :                 schedule_work(&old_rcpu->kthread_stop_wq);
     452                 :            :         }
     453                 :          0 : }
     454                 :            : 
     455                 :          0 : static int cpu_map_delete_elem(struct bpf_map *map, void *key)
     456                 :            : {
     457                 :            :         struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
     458                 :          0 :         u32 key_cpu = *(u32 *)key;
     459                 :            : 
     460         [ #  # ]:          0 :         if (key_cpu >= map->max_entries)
     461                 :            :                 return -EINVAL;
     462                 :            : 
     463                 :            :         /* notice caller map_delete_elem() use preempt_disable() */
     464                 :          0 :         __cpu_map_entry_replace(cmap, key_cpu, NULL);
     465                 :          0 :         return 0;
     466                 :            : }
     467                 :            : 
     468                 :          0 : static int cpu_map_update_elem(struct bpf_map *map, void *key, void *value,
     469                 :            :                                u64 map_flags)
     470                 :            : {
     471                 :            :         struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
     472                 :            :         struct bpf_cpu_map_entry *rcpu;
     473                 :            : 
     474                 :            :         /* Array index key correspond to CPU number */
     475                 :          0 :         u32 key_cpu = *(u32 *)key;
     476                 :            :         /* Value is the queue size */
     477                 :          0 :         u32 qsize = *(u32 *)value;
     478                 :            : 
     479         [ #  # ]:          0 :         if (unlikely(map_flags > BPF_EXIST))
     480                 :            :                 return -EINVAL;
     481         [ #  # ]:          0 :         if (unlikely(key_cpu >= cmap->map.max_entries))
     482                 :            :                 return -E2BIG;
     483         [ #  # ]:          0 :         if (unlikely(map_flags == BPF_NOEXIST))
     484                 :            :                 return -EEXIST;
     485         [ #  # ]:          0 :         if (unlikely(qsize > 16384)) /* sanity limit on qsize */
     486                 :            :                 return -EOVERFLOW;
     487                 :            : 
     488                 :            :         /* Make sure CPU is a valid possible cpu */
     489   [ #  #  #  # ]:          0 :         if (key_cpu >= nr_cpumask_bits || !cpu_possible(key_cpu))
     490                 :            :                 return -ENODEV;
     491                 :            : 
     492         [ #  # ]:          0 :         if (qsize == 0) {
     493                 :            :                 rcpu = NULL; /* Same as deleting */
     494                 :            :         } else {
     495                 :            :                 /* Updating qsize cause re-allocation of bpf_cpu_map_entry */
     496                 :          0 :                 rcpu = __cpu_map_entry_alloc(qsize, key_cpu, map->id);
     497         [ #  # ]:          0 :                 if (!rcpu)
     498                 :            :                         return -ENOMEM;
     499                 :          0 :                 rcpu->cmap = cmap;
     500                 :            :         }
     501                 :            :         rcu_read_lock();
     502                 :          0 :         __cpu_map_entry_replace(cmap, key_cpu, rcpu);
     503                 :            :         rcu_read_unlock();
     504                 :          0 :         return 0;
     505                 :            : }
     506                 :            : 
     507                 :          0 : static void cpu_map_free(struct bpf_map *map)
     508                 :            : {
     509                 :            :         struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
     510                 :            :         int cpu;
     511                 :            :         u32 i;
     512                 :            : 
     513                 :            :         /* At this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0,
     514                 :            :          * so the bpf programs (can be more than one that used this map) were
     515                 :            :          * disconnected from events. Wait for outstanding critical sections in
     516                 :            :          * these programs to complete. The rcu critical section only guarantees
     517                 :            :          * no further "XDP/bpf-side" reads against bpf_cpu_map->cpu_map.
     518                 :            :          * It does __not__ ensure pending flush operations (if any) are
     519                 :            :          * complete.
     520                 :            :          */
     521                 :            : 
     522                 :          0 :         bpf_clear_redirect_map(map);
     523                 :          0 :         synchronize_rcu();
     524                 :            : 
     525                 :            :         /* To ensure all pending flush operations have completed wait for flush
     526                 :            :          * list be empty on _all_ cpus. Because the above synchronize_rcu()
     527                 :            :          * ensures the map is disconnected from the program we can assume no new
     528                 :            :          * items will be added to the list.
     529                 :            :          */
     530         [ #  # ]:          0 :         for_each_online_cpu(cpu) {
     531                 :          0 :                 struct list_head *flush_list = per_cpu_ptr(cmap->flush_list, cpu);
     532                 :            : 
     533         [ #  # ]:          0 :                 while (!list_empty(flush_list))
     534                 :          0 :                         cond_resched();
     535                 :            :         }
     536                 :            : 
     537                 :            :         /* For cpu_map the remote CPUs can still be using the entries
     538                 :            :          * (struct bpf_cpu_map_entry).
     539                 :            :          */
     540         [ #  # ]:          0 :         for (i = 0; i < cmap->map.max_entries; i++) {
     541                 :            :                 struct bpf_cpu_map_entry *rcpu;
     542                 :            : 
     543                 :          0 :                 rcpu = READ_ONCE(cmap->cpu_map[i]);
     544         [ #  # ]:          0 :                 if (!rcpu)
     545                 :          0 :                         continue;
     546                 :            : 
     547                 :            :                 /* bq flush and cleanup happens after RCU graze-period */
     548                 :          0 :                 __cpu_map_entry_replace(cmap, i, NULL); /* call_rcu */
     549                 :            :         }
     550                 :          0 :         free_percpu(cmap->flush_list);
     551                 :          0 :         bpf_map_area_free(cmap->cpu_map);
     552                 :          0 :         kfree(cmap);
     553                 :          0 : }
     554                 :            : 
     555                 :          0 : struct bpf_cpu_map_entry *__cpu_map_lookup_elem(struct bpf_map *map, u32 key)
     556                 :            : {
     557                 :            :         struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
     558                 :            :         struct bpf_cpu_map_entry *rcpu;
     559                 :            : 
     560   [ #  #  #  # ]:          0 :         if (key >= map->max_entries)
     561                 :            :                 return NULL;
     562                 :            : 
     563                 :          0 :         rcpu = READ_ONCE(cmap->cpu_map[key]);
     564                 :          0 :         return rcpu;
     565                 :            : }
     566                 :            : 
     567                 :          0 : static void *cpu_map_lookup_elem(struct bpf_map *map, void *key)
     568                 :            : {
     569                 :            :         struct bpf_cpu_map_entry *rcpu =
     570                 :          0 :                 __cpu_map_lookup_elem(map, *(u32 *)key);
     571                 :            : 
     572         [ #  # ]:          0 :         return rcpu ? &rcpu->qsize : NULL;
     573                 :            : }
     574                 :            : 
     575                 :          0 : static int cpu_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
     576                 :            : {
     577                 :            :         struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
     578         [ #  # ]:          0 :         u32 index = key ? *(u32 *)key : U32_MAX;
     579                 :            :         u32 *next = next_key;
     580                 :            : 
     581         [ #  # ]:          0 :         if (index >= cmap->map.max_entries) {
     582                 :          0 :                 *next = 0;
     583                 :          0 :                 return 0;
     584                 :            :         }
     585                 :            : 
     586         [ #  # ]:          0 :         if (index == cmap->map.max_entries - 1)
     587                 :            :                 return -ENOENT;
     588                 :          0 :         *next = index + 1;
     589                 :          0 :         return 0;
     590                 :            : }
     591                 :            : 
     592                 :            : const struct bpf_map_ops cpu_map_ops = {
     593                 :            :         .map_alloc              = cpu_map_alloc,
     594                 :            :         .map_free               = cpu_map_free,
     595                 :            :         .map_delete_elem        = cpu_map_delete_elem,
     596                 :            :         .map_update_elem        = cpu_map_update_elem,
     597                 :            :         .map_lookup_elem        = cpu_map_lookup_elem,
     598                 :            :         .map_get_next_key       = cpu_map_get_next_key,
     599                 :            :         .map_check_btf          = map_check_no_btf,
     600                 :            : };
     601                 :            : 
     602                 :          0 : static int bq_flush_to_queue(struct xdp_bulk_queue *bq, bool in_napi_ctx)
     603                 :            : {
     604                 :          0 :         struct bpf_cpu_map_entry *rcpu = bq->obj;
     605                 :            :         unsigned int processed = 0, drops = 0;
     606                 :          0 :         const int to_cpu = rcpu->cpu;
     607                 :            :         struct ptr_ring *q;
     608                 :            :         int i;
     609                 :            : 
     610         [ #  # ]:          0 :         if (unlikely(!bq->count))
     611                 :            :                 return 0;
     612                 :            : 
     613                 :          0 :         q = rcpu->queue;
     614                 :            :         spin_lock(&q->producer_lock);
     615                 :            : 
     616         [ #  # ]:          0 :         for (i = 0; i < bq->count; i++) {
     617                 :          0 :                 struct xdp_frame *xdpf = bq->q[i];
     618                 :            :                 int err;
     619                 :            : 
     620                 :          0 :                 err = __ptr_ring_produce(q, xdpf);
     621         [ #  # ]:          0 :                 if (err) {
     622                 :          0 :                         drops++;
     623         [ #  # ]:          0 :                         if (likely(in_napi_ctx))
     624                 :          0 :                                 xdp_return_frame_rx_napi(xdpf);
     625                 :            :                         else
     626                 :          0 :                                 xdp_return_frame(xdpf);
     627                 :            :                 }
     628                 :          0 :                 processed++;
     629                 :            :         }
     630                 :          0 :         bq->count = 0;
     631                 :            :         spin_unlock(&q->producer_lock);
     632                 :            : 
     633                 :            :         __list_del_clearprev(&bq->flush_node);
     634                 :            : 
     635                 :            :         /* Feedback loop via tracepoints */
     636                 :          0 :         trace_xdp_cpumap_enqueue(rcpu->map_id, processed, drops, to_cpu);
     637                 :          0 :         return 0;
     638                 :            : }
     639                 :            : 
     640                 :            : /* Runs under RCU-read-side, plus in softirq under NAPI protection.
     641                 :            :  * Thus, safe percpu variable access.
     642                 :            :  */
     643                 :          0 : static int bq_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf)
     644                 :            : {
     645                 :          0 :         struct list_head *flush_list = this_cpu_ptr(rcpu->cmap->flush_list);
     646                 :          0 :         struct xdp_bulk_queue *bq = this_cpu_ptr(rcpu->bulkq);
     647                 :            : 
     648         [ #  # ]:          0 :         if (unlikely(bq->count == CPU_MAP_BULK_SIZE))
     649                 :          0 :                 bq_flush_to_queue(bq, true);
     650                 :            : 
     651                 :            :         /* Notice, xdp_buff/page MUST be queued here, long enough for
     652                 :            :          * driver to code invoking us to finished, due to driver
     653                 :            :          * (e.g. ixgbe) recycle tricks based on page-refcnt.
     654                 :            :          *
     655                 :            :          * Thus, incoming xdp_frame is always queued here (else we race
     656                 :            :          * with another CPU on page-refcnt and remaining driver code).
     657                 :            :          * Queue time is very short, as driver will invoke flush
     658                 :            :          * operation, when completing napi->poll call.
     659                 :            :          */
     660                 :          0 :         bq->q[bq->count++] = xdpf;
     661                 :            : 
     662         [ #  # ]:          0 :         if (!bq->flush_node.prev)
     663                 :          0 :                 list_add(&bq->flush_node, flush_list);
     664                 :            : 
     665                 :          0 :         return 0;
     666                 :            : }
     667                 :            : 
     668                 :          0 : int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_buff *xdp,
     669                 :            :                     struct net_device *dev_rx)
     670                 :            : {
     671                 :            :         struct xdp_frame *xdpf;
     672                 :            : 
     673                 :          0 :         xdpf = convert_to_xdp_frame(xdp);
     674         [ #  # ]:          0 :         if (unlikely(!xdpf))
     675                 :            :                 return -EOVERFLOW;
     676                 :            : 
     677                 :            :         /* Info needed when constructing SKB on remote CPU */
     678                 :          0 :         xdpf->dev_rx = dev_rx;
     679                 :            : 
     680                 :          0 :         bq_enqueue(rcpu, xdpf);
     681                 :          0 :         return 0;
     682                 :            : }
     683                 :            : 
     684                 :          0 : void __cpu_map_flush(struct bpf_map *map)
     685                 :            : {
     686                 :            :         struct bpf_cpu_map *cmap = container_of(map, struct bpf_cpu_map, map);
     687                 :          0 :         struct list_head *flush_list = this_cpu_ptr(cmap->flush_list);
     688                 :            :         struct xdp_bulk_queue *bq, *tmp;
     689                 :            : 
     690         [ #  # ]:          0 :         list_for_each_entry_safe(bq, tmp, flush_list, flush_node) {
     691                 :          0 :                 bq_flush_to_queue(bq, true);
     692                 :            : 
     693                 :            :                 /* If already running, costs spin_lock_irqsave + smb_mb */
     694                 :          0 :                 wake_up_process(bq->obj->kthread);
     695                 :            :         }
     696                 :          0 : }

Generated by: LCOV version 1.14