Path: blob/master/tools/testing/selftests/bpf/bpf_arena_htab.h
26285 views
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */1/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */2#pragma once3#include <errno.h>4#include "bpf_arena_alloc.h"5#include "bpf_arena_list.h"67struct htab_bucket {8struct arena_list_head head;9};10typedef struct htab_bucket __arena htab_bucket_t;1112struct htab {13htab_bucket_t *buckets;14int n_buckets;15};16typedef struct htab __arena htab_t;1718static inline htab_bucket_t *__select_bucket(htab_t *htab, __u32 hash)19{20htab_bucket_t *b = htab->buckets;2122cast_kern(b);23return &b[hash & (htab->n_buckets - 1)];24}2526static inline arena_list_head_t *select_bucket(htab_t *htab, __u32 hash)27{28return &__select_bucket(htab, hash)->head;29}3031struct hashtab_elem {32int hash;33int key;34int value;35struct arena_list_node hash_node;36};37typedef struct hashtab_elem __arena hashtab_elem_t;3839static hashtab_elem_t *lookup_elem_raw(arena_list_head_t *head, __u32 hash, int key)40{41hashtab_elem_t *l;4243list_for_each_entry(l, head, hash_node)44if (l->hash == hash && l->key == key)45return l;4647return NULL;48}4950static int htab_hash(int key)51{52return key;53}5455__weak int htab_lookup_elem(htab_t *htab __arg_arena, int key)56{57hashtab_elem_t *l_old;58arena_list_head_t *head;5960cast_kern(htab);61head = select_bucket(htab, key);62l_old = lookup_elem_raw(head, htab_hash(key), key);63if (l_old)64return l_old->value;65return 0;66}6768__weak int htab_update_elem(htab_t *htab __arg_arena, int key, int value)69{70hashtab_elem_t *l_new = NULL, *l_old;71arena_list_head_t *head;7273cast_kern(htab);74head = select_bucket(htab, key);75l_old = lookup_elem_raw(head, htab_hash(key), key);7677l_new = bpf_alloc(sizeof(*l_new));78if (!l_new)79return -ENOMEM;80l_new->key = key;81l_new->hash = htab_hash(key);82l_new->value = value;8384list_add_head(&l_new->hash_node, head);85if (l_old) {86list_del(&l_old->hash_node);87bpf_free(l_old);88}89return 0;90}9192void htab_init(htab_t *htab)93{94void __arena *buckets = bpf_arena_alloc_pages(&arena, NULL, 2, NUMA_NO_NODE, 0);9596cast_user(buckets);97htab->buckets = buckets;98htab->n_buckets = 2 * PAGE_SIZE / sizeof(struct htab_bucket);99}100101102