linux/net/core/xdp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* net/core/xdp.c
   3 *
   4 * Copyright (c) 2017 Jesper Dangaard Brouer, Red Hat Inc.
   5 */
   6#include <linux/bpf.h>
   7#include <linux/filter.h>
   8#include <linux/types.h>
   9#include <linux/mm.h>
  10#include <linux/netdevice.h>
  11#include <linux/slab.h>
  12#include <linux/idr.h>
  13#include <linux/rhashtable.h>
  14#include <linux/bug.h>
  15#include <net/page_pool.h>
  16
  17#include <net/xdp.h>
  18#include <net/xdp_priv.h> /* struct xdp_mem_allocator */
  19#include <trace/events/xdp.h>
  20#include <net/xdp_sock_drv.h>
  21
  22#define REG_STATE_NEW           0x0
  23#define REG_STATE_REGISTERED    0x1
  24#define REG_STATE_UNREGISTERED  0x2
  25#define REG_STATE_UNUSED        0x3
  26
  27static DEFINE_IDA(mem_id_pool);
  28static DEFINE_MUTEX(mem_id_lock);
  29#define MEM_ID_MAX 0xFFFE
  30#define MEM_ID_MIN 1
  31static int mem_id_next = MEM_ID_MIN;
  32
  33static bool mem_id_init; /* false */
  34static struct rhashtable *mem_id_ht;
  35
  36static u32 xdp_mem_id_hashfn(const void *data, u32 len, u32 seed)
  37{
  38        const u32 *k = data;
  39        const u32 key = *k;
  40
  41        BUILD_BUG_ON(sizeof_field(struct xdp_mem_allocator, mem.id)
  42                     != sizeof(u32));
  43
  44        /* Use cyclic increasing ID as direct hash key */
  45        return key;
  46}
  47
  48static int xdp_mem_id_cmp(struct rhashtable_compare_arg *arg,
  49                          const void *ptr)
  50{
  51        const struct xdp_mem_allocator *xa = ptr;
  52        u32 mem_id = *(u32 *)arg->key;
  53
  54        return xa->mem.id != mem_id;
  55}
  56
  57static const struct rhashtable_params mem_id_rht_params = {
  58        .nelem_hint = 64,
  59        .head_offset = offsetof(struct xdp_mem_allocator, node),
  60        .key_offset  = offsetof(struct xdp_mem_allocator, mem.id),
  61        .key_len = sizeof_field(struct xdp_mem_allocator, mem.id),
  62        .max_size = MEM_ID_MAX,
  63        .min_size = 8,
  64        .automatic_shrinking = true,
  65        .hashfn    = xdp_mem_id_hashfn,
  66        .obj_cmpfn = xdp_mem_id_cmp,
  67};
  68
  69static void __xdp_mem_allocator_rcu_free(struct rcu_head *rcu)
  70{
  71        struct xdp_mem_allocator *xa;
  72
  73        xa = container_of(rcu, struct xdp_mem_allocator, rcu);
  74
  75        /* Allow this ID to be reused */
  76        ida_simple_remove(&mem_id_pool, xa->mem.id);
  77
  78        kfree(xa);
  79}
  80
  81static void mem_xa_remove(struct xdp_mem_allocator *xa)
  82{
  83        trace_mem_disconnect(xa);
  84
  85        if (!rhashtable_remove_fast(mem_id_ht, &xa->node, mem_id_rht_params))
  86                call_rcu(&xa->rcu, __xdp_mem_allocator_rcu_free);
  87}
  88
  89static void mem_allocator_disconnect(void *allocator)
  90{
  91        struct xdp_mem_allocator *xa;
  92        struct rhashtable_iter iter;
  93
  94        mutex_lock(&mem_id_lock);
  95
  96        rhashtable_walk_enter(mem_id_ht, &iter);
  97        do {
  98                rhashtable_walk_start(&iter);
  99
 100                while ((xa = rhashtable_walk_next(&iter)) && !IS_ERR(xa)) {
 101                        if (xa->allocator == allocator)
 102                                mem_xa_remove(xa);
 103                }
 104
 105                rhashtable_walk_stop(&iter);
 106
 107        } while (xa == ERR_PTR(-EAGAIN));
 108        rhashtable_walk_exit(&iter);
 109
 110        mutex_unlock(&mem_id_lock);
 111}
 112
 113void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq)
 114{
 115        struct xdp_mem_allocator *xa;
 116        int id = xdp_rxq->mem.id;
 117
 118        if (xdp_rxq->reg_state != REG_STATE_REGISTERED) {
 119                WARN(1, "Missing register, driver bug");
 120                return;
 121        }
 122
 123        if (id == 0)
 124                return;
 125
 126        if (xdp_rxq->mem.type == MEM_TYPE_PAGE_POOL) {
 127                rcu_read_lock();
 128                xa = rhashtable_lookup(mem_id_ht, &id, mem_id_rht_params);
 129                page_pool_destroy(xa->page_pool);
 130                rcu_read_unlock();
 131        }
 132}
 133EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg_mem_model);
 134
 135void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq)
 136{
 137        /* Simplify driver cleanup code paths, allow unreg "unused" */
 138        if (xdp_rxq->reg_state == REG_STATE_UNUSED)
 139                return;
 140
 141        WARN(!(xdp_rxq->reg_state == REG_STATE_REGISTERED), "Driver BUG");
 142
 143        xdp_rxq_info_unreg_mem_model(xdp_rxq);
 144
 145        xdp_rxq->reg_state = REG_STATE_UNREGISTERED;
 146        xdp_rxq->dev = NULL;
 147
 148        /* Reset mem info to defaults */
 149        xdp_rxq->mem.id = 0;
 150        xdp_rxq->mem.type = 0;
 151}
 152EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg);
 153
 154static void xdp_rxq_info_init(struct xdp_rxq_info *xdp_rxq)
 155{
 156        memset(xdp_rxq, 0, sizeof(*xdp_rxq));
 157}
 158
 159/* Returns 0 on success, negative on failure */
 160int xdp_rxq_info_reg(struct xdp_rxq_info *xdp_rxq,
 161                     struct net_device *dev, u32 queue_index, unsigned int napi_id)
 162{
 163        if (xdp_rxq->reg_state == REG_STATE_UNUSED) {
 164                WARN(1, "Driver promised not to register this");
 165                return -EINVAL;
 166        }
 167
 168        if (xdp_rxq->reg_state == REG_STATE_REGISTERED) {
 169                WARN(1, "Missing unregister, handled but fix driver");
 170                xdp_rxq_info_unreg(xdp_rxq);
 171        }
 172
 173        if (!dev) {
 174                WARN(1, "Missing net_device from driver");
 175                return -ENODEV;
 176        }
 177
 178        /* State either UNREGISTERED or NEW */
 179        xdp_rxq_info_init(xdp_rxq);
 180        xdp_rxq->dev = dev;
 181        xdp_rxq->queue_index = queue_index;
 182        xdp_rxq->napi_id = napi_id;
 183
 184        xdp_rxq->reg_state = REG_STATE_REGISTERED;
 185        return 0;
 186}
 187EXPORT_SYMBOL_GPL(xdp_rxq_info_reg);
 188
 189void xdp_rxq_info_unused(struct xdp_rxq_info *xdp_rxq)
 190{
 191        xdp_rxq->reg_state = REG_STATE_UNUSED;
 192}
 193EXPORT_SYMBOL_GPL(xdp_rxq_info_unused);
 194
 195bool xdp_rxq_info_is_reg(struct xdp_rxq_info *xdp_rxq)
 196{
 197        return (xdp_rxq->reg_state == REG_STATE_REGISTERED);
 198}
 199EXPORT_SYMBOL_GPL(xdp_rxq_info_is_reg);
 200
 201static int __mem_id_init_hash_table(void)
 202{
 203        struct rhashtable *rht;
 204        int ret;
 205
 206        if (unlikely(mem_id_init))
 207                return 0;
 208
 209        rht = kzalloc(sizeof(*rht), GFP_KERNEL);
 210        if (!rht)
 211                return -ENOMEM;
 212
 213        ret = rhashtable_init(rht, &mem_id_rht_params);
 214        if (ret < 0) {
 215                kfree(rht);
 216                return ret;
 217        }
 218        mem_id_ht = rht;
 219        smp_mb(); /* mutex lock should provide enough pairing */
 220        mem_id_init = true;
 221
 222        return 0;
 223}
 224
 225/* Allocate a cyclic ID that maps to allocator pointer.
 226 * See: https://www.kernel.org/doc/html/latest/core-api/idr.html
 227 *
 228 * Caller must lock mem_id_lock.
 229 */
 230static int __mem_id_cyclic_get(gfp_t gfp)
 231{
 232        int retries = 1;
 233        int id;
 234
 235again:
 236        id = ida_simple_get(&mem_id_pool, mem_id_next, MEM_ID_MAX, gfp);
 237        if (id < 0) {
 238                if (id == -ENOSPC) {
 239                        /* Cyclic allocator, reset next id */
 240                        if (retries--) {
 241                                mem_id_next = MEM_ID_MIN;
 242                                goto again;
 243                        }
 244                }
 245                return id; /* errno */
 246        }
 247        mem_id_next = id + 1;
 248
 249        return id;
 250}
 251
 252static bool __is_supported_mem_type(enum xdp_mem_type type)
 253{
 254        if (type == MEM_TYPE_PAGE_POOL)
 255                return is_page_pool_compiled_in();
 256
 257        if (type >= MEM_TYPE_MAX)
 258                return false;
 259
 260        return true;
 261}
 262
 263int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq,
 264                               enum xdp_mem_type type, void *allocator)
 265{
 266        struct xdp_mem_allocator *xdp_alloc;
 267        gfp_t gfp = GFP_KERNEL;
 268        int id, errno, ret;
 269        void *ptr;
 270
 271        if (xdp_rxq->reg_state != REG_STATE_REGISTERED) {
 272                WARN(1, "Missing register, driver bug");
 273                return -EFAULT;
 274        }
 275
 276        if (!__is_supported_mem_type(type))
 277                return -EOPNOTSUPP;
 278
 279        xdp_rxq->mem.type = type;
 280
 281        if (!allocator) {
 282                if (type == MEM_TYPE_PAGE_POOL)
 283                        return -EINVAL; /* Setup time check page_pool req */
 284                return 0;
 285        }
 286
 287        /* Delay init of rhashtable to save memory if feature isn't used */
 288        if (!mem_id_init) {
 289                mutex_lock(&mem_id_lock);
 290                ret = __mem_id_init_hash_table();
 291                mutex_unlock(&mem_id_lock);
 292                if (ret < 0) {
 293                        WARN_ON(1);
 294                        return ret;
 295                }
 296        }
 297
 298        xdp_alloc = kzalloc(sizeof(*xdp_alloc), gfp);
 299        if (!xdp_alloc)
 300                return -ENOMEM;
 301
 302        mutex_lock(&mem_id_lock);
 303        id = __mem_id_cyclic_get(gfp);
 304        if (id < 0) {
 305                errno = id;
 306                goto err;
 307        }
 308        xdp_rxq->mem.id = id;
 309        xdp_alloc->mem  = xdp_rxq->mem;
 310        xdp_alloc->allocator = allocator;
 311
 312        /* Insert allocator into ID lookup table */
 313        ptr = rhashtable_insert_slow(mem_id_ht, &id, &xdp_alloc->node);
 314        if (IS_ERR(ptr)) {
 315                ida_simple_remove(&mem_id_pool, xdp_rxq->mem.id);
 316                xdp_rxq->mem.id = 0;
 317                errno = PTR_ERR(ptr);
 318                goto err;
 319        }
 320
 321        if (type == MEM_TYPE_PAGE_POOL)
 322                page_pool_use_xdp_mem(allocator, mem_allocator_disconnect);
 323
 324        mutex_unlock(&mem_id_lock);
 325
 326        trace_mem_connect(xdp_alloc, xdp_rxq);
 327        return 0;
 328err:
 329        mutex_unlock(&mem_id_lock);
 330        kfree(xdp_alloc);
 331        return errno;
 332}
 333EXPORT_SYMBOL_GPL(xdp_rxq_info_reg_mem_model);
 334
 335/* XDP RX runs under NAPI protection, and in different delivery error
 336 * scenarios (e.g. queue full), it is possible to return the xdp_frame
 337 * while still leveraging this protection.  The @napi_direct boolean
 338 * is used for those calls sites.  Thus, allowing for faster recycling
 339 * of xdp_frames/pages in those cases.
 340 */
 341static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
 342                         struct xdp_buff *xdp)
 343{
 344        struct xdp_mem_allocator *xa;
 345        struct page *page;
 346
 347        switch (mem->type) {
 348        case MEM_TYPE_PAGE_POOL:
 349                rcu_read_lock();
 350                /* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */
 351                xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
 352                page = virt_to_head_page(data);
 353                if (napi_direct && xdp_return_frame_no_direct())
 354                        napi_direct = false;
 355                page_pool_put_full_page(xa->page_pool, page, napi_direct);
 356                rcu_read_unlock();
 357                break;
 358        case MEM_TYPE_PAGE_SHARED:
 359                page_frag_free(data);
 360                break;
 361        case MEM_TYPE_PAGE_ORDER0:
 362                page = virt_to_page(data); /* Assumes order0 page*/
 363                put_page(page);
 364                break;
 365        case MEM_TYPE_XSK_BUFF_POOL:
 366                /* NB! Only valid from an xdp_buff! */
 367                xsk_buff_free(xdp);
 368                break;
 369        default:
 370                /* Not possible, checked in xdp_rxq_info_reg_mem_model() */
 371                WARN(1, "Incorrect XDP memory type (%d) usage", mem->type);
 372                break;
 373        }
 374}
 375
 376void xdp_return_frame(struct xdp_frame *xdpf)
 377{
 378        __xdp_return(xdpf->data, &xdpf->mem, false, NULL);
 379}
 380EXPORT_SYMBOL_GPL(xdp_return_frame);
 381
 382void xdp_return_frame_rx_napi(struct xdp_frame *xdpf)
 383{
 384        __xdp_return(xdpf->data, &xdpf->mem, true, NULL);
 385}
 386EXPORT_SYMBOL_GPL(xdp_return_frame_rx_napi);
 387
 388/* XDP bulk APIs introduce a defer/flush mechanism to return
 389 * pages belonging to the same xdp_mem_allocator object
 390 * (identified via the mem.id field) in bulk to optimize
 391 * I-cache and D-cache.
 392 * The bulk queue size is set to 16 to be aligned to how
 393 * XDP_REDIRECT bulking works. The bulk is flushed when
 394 * it is full or when mem.id changes.
 395 * xdp_frame_bulk is usually stored/allocated on the function
 396 * call-stack to avoid locking penalties.
 397 */
 398void xdp_flush_frame_bulk(struct xdp_frame_bulk *bq)
 399{
 400        struct xdp_mem_allocator *xa = bq->xa;
 401
 402        if (unlikely(!xa || !bq->count))
 403                return;
 404
 405        page_pool_put_page_bulk(xa->page_pool, bq->q, bq->count);
 406        /* bq->xa is not cleared to save lookup, if mem.id same in next bulk */
 407        bq->count = 0;
 408}
 409EXPORT_SYMBOL_GPL(xdp_flush_frame_bulk);
 410
 411/* Must be called with rcu_read_lock held */
 412void xdp_return_frame_bulk(struct xdp_frame *xdpf,
 413                           struct xdp_frame_bulk *bq)
 414{
 415        struct xdp_mem_info *mem = &xdpf->mem;
 416        struct xdp_mem_allocator *xa;
 417
 418        if (mem->type != MEM_TYPE_PAGE_POOL) {
 419                __xdp_return(xdpf->data, &xdpf->mem, false, NULL);
 420                return;
 421        }
 422
 423        xa = bq->xa;
 424        if (unlikely(!xa)) {
 425                xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
 426                bq->count = 0;
 427                bq->xa = xa;
 428        }
 429
 430        if (bq->count == XDP_BULK_QUEUE_SIZE)
 431                xdp_flush_frame_bulk(bq);
 432
 433        if (unlikely(mem->id != xa->mem.id)) {
 434                xdp_flush_frame_bulk(bq);
 435                bq->xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
 436        }
 437
 438        bq->q[bq->count++] = xdpf->data;
 439}
 440EXPORT_SYMBOL_GPL(xdp_return_frame_bulk);
 441
 442void xdp_return_buff(struct xdp_buff *xdp)
 443{
 444        __xdp_return(xdp->data, &xdp->rxq->mem, true, xdp);
 445}
 446
 447/* Only called for MEM_TYPE_PAGE_POOL see xdp.h */
 448void __xdp_release_frame(void *data, struct xdp_mem_info *mem)
 449{
 450        struct xdp_mem_allocator *xa;
 451        struct page *page;
 452
 453        rcu_read_lock();
 454        xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
 455        page = virt_to_head_page(data);
 456        if (xa)
 457                page_pool_release_page(xa->page_pool, page);
 458        rcu_read_unlock();
 459}
 460EXPORT_SYMBOL_GPL(__xdp_release_frame);
 461
 462void xdp_attachment_setup(struct xdp_attachment_info *info,
 463                          struct netdev_bpf *bpf)
 464{
 465        if (info->prog)
 466                bpf_prog_put(info->prog);
 467        info->prog = bpf->prog;
 468        info->flags = bpf->flags;
 469}
 470EXPORT_SYMBOL_GPL(xdp_attachment_setup);
 471
 472struct xdp_frame *xdp_convert_zc_to_xdp_frame(struct xdp_buff *xdp)
 473{
 474        unsigned int metasize, totsize;
 475        void *addr, *data_to_copy;
 476        struct xdp_frame *xdpf;
 477        struct page *page;
 478
 479        /* Clone into a MEM_TYPE_PAGE_ORDER0 xdp_frame. */
 480        metasize = xdp_data_meta_unsupported(xdp) ? 0 :
 481                   xdp->data - xdp->data_meta;
 482        totsize = xdp->data_end - xdp->data + metasize;
 483
 484        if (sizeof(*xdpf) + totsize > PAGE_SIZE)
 485                return NULL;
 486
 487        page = dev_alloc_page();
 488        if (!page)
 489                return NULL;
 490
 491        addr = page_to_virt(page);
 492        xdpf = addr;
 493        memset(xdpf, 0, sizeof(*xdpf));
 494
 495        addr += sizeof(*xdpf);
 496        data_to_copy = metasize ? xdp->data_meta : xdp->data;
 497        memcpy(addr, data_to_copy, totsize);
 498
 499        xdpf->data = addr + metasize;
 500        xdpf->len = totsize - metasize;
 501        xdpf->headroom = 0;
 502        xdpf->metasize = metasize;
 503        xdpf->frame_sz = PAGE_SIZE;
 504        xdpf->mem.type = MEM_TYPE_PAGE_ORDER0;
 505
 506        xsk_buff_free(xdp);
 507        return xdpf;
 508}
 509EXPORT_SYMBOL_GPL(xdp_convert_zc_to_xdp_frame);
 510
 511/* Used by XDP_WARN macro, to avoid inlining WARN() in fast-path */
 512void xdp_warn(const char *msg, const char *func, const int line)
 513{
 514        WARN(1, "XDP_WARN: %s(line:%d): %s\n", func, line, msg);
 515};
 516EXPORT_SYMBOL_GPL(xdp_warn);
 517
 518int xdp_alloc_skb_bulk(void **skbs, int n_skb, gfp_t gfp)
 519{
 520        n_skb = kmem_cache_alloc_bulk(skbuff_head_cache, gfp,
 521                                      n_skb, skbs);
 522        if (unlikely(!n_skb))
 523                return -ENOMEM;
 524
 525        return 0;
 526}
 527EXPORT_SYMBOL_GPL(xdp_alloc_skb_bulk);
 528
 529struct sk_buff *__xdp_build_skb_from_frame(struct xdp_frame *xdpf,
 530                                           struct sk_buff *skb,
 531                                           struct net_device *dev)
 532{
 533        unsigned int headroom, frame_size;
 534        void *hard_start;
 535
 536        /* Part of headroom was reserved to xdpf */
 537        headroom = sizeof(*xdpf) + xdpf->headroom;
 538
 539        /* Memory size backing xdp_frame data already have reserved
 540         * room for build_skb to place skb_shared_info in tailroom.
 541         */
 542        frame_size = xdpf->frame_sz;
 543
 544        hard_start = xdpf->data - headroom;
 545        skb = build_skb_around(skb, hard_start, frame_size);
 546        if (unlikely(!skb))
 547                return NULL;
 548
 549        skb_reserve(skb, headroom);
 550        __skb_put(skb, xdpf->len);
 551        if (xdpf->metasize)
 552                skb_metadata_set(skb, xdpf->metasize);
 553
 554        /* Essential SKB info: protocol and skb->dev */
 555        skb->protocol = eth_type_trans(skb, dev);
 556
 557        /* Optional SKB info, currently missing:
 558         * - HW checksum info           (skb->ip_summed)
 559         * - HW RX hash                 (skb_set_hash)
 560         * - RX ring dev queue index    (skb_record_rx_queue)
 561         */
 562
 563        /* Until page_pool get SKB return path, release DMA here */
 564        xdp_release_frame(xdpf);
 565
 566        /* Allow SKB to reuse area used by xdp_frame */
 567        xdp_scrub_frame(xdpf);
 568
 569        return skb;
 570}
 571EXPORT_SYMBOL_GPL(__xdp_build_skb_from_frame);
 572
 573struct sk_buff *xdp_build_skb_from_frame(struct xdp_frame *xdpf,
 574                                         struct net_device *dev)
 575{
 576        struct sk_buff *skb;
 577
 578        skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC);
 579        if (unlikely(!skb))
 580                return NULL;
 581
 582        memset(skb, 0, offsetof(struct sk_buff, tail));
 583
 584        return __xdp_build_skb_from_frame(xdpf, skb, dev);
 585}
 586EXPORT_SYMBOL_GPL(xdp_build_skb_from_frame);
 587