Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/testing/selftests/bpf/progs/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 8 kB image not shown  

Quelle  linked_list.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
#include <vmlinux.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_core_read.h>
#include "bpf_experimental.h"
#include "bpf_misc.h"

#include "linked_list.h"

struct head_nested_inner {
 struct bpf_spin_lock lock;
 struct bpf_list_head head __contains(foo, node2);
};

struct head_nested {
 int dummy;
 struct head_nested_inner inner;
};

private(C) struct bpf_spin_lock glock_c;
private(C) struct bpf_list_head ghead_array[2] __contains(foo, node2);
private(C) struct bpf_list_head ghead_array_one[1] __contains(foo, node2);

private(D) struct head_nested ghead_nested;

static __always_inline
int list_push_pop(struct bpf_spin_lock *lock, struct bpf_list_head *head, bool leave_in_map)
{
 struct bpf_list_node *n;
 struct foo *f;

 f = bpf_obj_new(typeof(*f));
 if (!f)
  return 2;

 bpf_spin_lock(lock);
 n = bpf_list_pop_front(head);
 bpf_spin_unlock(lock);
 if (n) {
  bpf_obj_drop(container_of(n, struct foo, node2));
  bpf_obj_drop(f);
  return 3;
 }

 bpf_spin_lock(lock);
 n = bpf_list_pop_back(head);
 bpf_spin_unlock(lock);
 if (n) {
  bpf_obj_drop(container_of(n, struct foo, node2));
  bpf_obj_drop(f);
  return 4;
 }


 bpf_spin_lock(lock);
 f->data = 42;
 bpf_list_push_front(head, &f->node2);
 bpf_spin_unlock(lock);
 if (leave_in_map)
  return 0;
 bpf_spin_lock(lock);
 n = bpf_list_pop_back(head);
 bpf_spin_unlock(lock);
 if (!n)
  return 5;
 f = container_of(n, struct foo, node2);
 if (f->data != 42) {
  bpf_obj_drop(f);
  return 6;
 }

 bpf_spin_lock(lock);
 f->data = 13;
 bpf_list_push_front(head, &f->node2);
 bpf_spin_unlock(lock);
 bpf_spin_lock(lock);
 n = bpf_list_pop_front(head);
 bpf_spin_unlock(lock);
 if (!n)
  return 7;
 f = container_of(n, struct foo, node2);
 if (f->data != 13) {
  bpf_obj_drop(f);
  return 8;
 }
 bpf_obj_drop(f);

 bpf_spin_lock(lock);
 n = bpf_list_pop_front(head);
 bpf_spin_unlock(lock);
 if (n) {
  bpf_obj_drop(container_of(n, struct foo, node2));
  return 9;
 }

 bpf_spin_lock(lock);
 n = bpf_list_pop_back(head);
 bpf_spin_unlock(lock);
 if (n) {
  bpf_obj_drop(container_of(n, struct foo, node2));
  return 10;
 }
 return 0;
}


static __always_inline
int list_push_pop_multiple(struct bpf_spin_lock *lock, struct bpf_list_head *head, bool leave_in_map)
{
 struct bpf_list_node *n;
 struct foo *f[200], *pf;
 int i;

 /* Loop following this check adds nodes 2-at-a-time in order to
 * validate multiple release_on_unlock release logic
 */

 if (ARRAY_SIZE(f) % 2)
  return 10;

 for (i = 0; i < ARRAY_SIZE(f); i += 2) {
  f[i] = bpf_obj_new(typeof(**f));
  if (!f[i])
   return 2;
  f[i]->data = i;

  f[i + 1] = bpf_obj_new(typeof(**f));
  if (!f[i + 1]) {
   bpf_obj_drop(f[i]);
   return 9;
  }
  f[i + 1]->data = i + 1;

  bpf_spin_lock(lock);
  bpf_list_push_front(head, &f[i]->node2);
  bpf_list_push_front(head, &f[i + 1]->node2);
  bpf_spin_unlock(lock);
 }

 for (i = 0; i < ARRAY_SIZE(f); i++) {
  bpf_spin_lock(lock);
  n = bpf_list_pop_front(head);
  bpf_spin_unlock(lock);
  if (!n)
   return 3;
  pf = container_of(n, struct foo, node2);
  if (pf->data != (ARRAY_SIZE(f) - i - 1)) {
   bpf_obj_drop(pf);
   return 4;
  }
  bpf_spin_lock(lock);
  bpf_list_push_back(head, &pf->node2);
  bpf_spin_unlock(lock);
 }

 if (leave_in_map)
  return 0;

 for (i = 0; i < ARRAY_SIZE(f); i++) {
  bpf_spin_lock(lock);
  n = bpf_list_pop_back(head);
  bpf_spin_unlock(lock);
  if (!n)
   return 5;
  pf = container_of(n, struct foo, node2);
  if (pf->data != i) {
   bpf_obj_drop(pf);
   return 6;
  }
  bpf_obj_drop(pf);
 }
 bpf_spin_lock(lock);
 n = bpf_list_pop_back(head);
 bpf_spin_unlock(lock);
 if (n) {
  bpf_obj_drop(container_of(n, struct foo, node2));
  return 7;
 }

 bpf_spin_lock(lock);
 n = bpf_list_pop_front(head);
 bpf_spin_unlock(lock);
 if (n) {
  bpf_obj_drop(container_of(n, struct foo, node2));
  return 8;
 }
 return 0;
}

static __always_inline
int list_in_list(struct bpf_spin_lock *lock, struct bpf_list_head *head, bool leave_in_map)
{
 struct bpf_list_node *n;
 struct bar *ba[8], *b;
 struct foo *f;
 int i;

 f = bpf_obj_new(typeof(*f));
 if (!f)
  return 2;
 for (i = 0; i < ARRAY_SIZE(ba); i++) {
  b = bpf_obj_new(typeof(*b));
  if (!b) {
   bpf_obj_drop(f);
   return 3;
  }
  b->data = i;
  bpf_spin_lock(&f->lock);
  bpf_list_push_back(&f->head, &b->node);
  bpf_spin_unlock(&f->lock);
 }

 bpf_spin_lock(lock);
 f->data = 42;
 bpf_list_push_front(head, &f->node2);
 bpf_spin_unlock(lock);

 if (leave_in_map)
  return 0;

 bpf_spin_lock(lock);
 n = bpf_list_pop_front(head);
 bpf_spin_unlock(lock);
 if (!n)
  return 4;
 f = container_of(n, struct foo, node2);
 if (f->data != 42) {
  bpf_obj_drop(f);
  return 5;
 }

 for (i = 0; i < ARRAY_SIZE(ba); i++) {
  bpf_spin_lock(&f->lock);
  n = bpf_list_pop_front(&f->head);
  bpf_spin_unlock(&f->lock);
  if (!n) {
   bpf_obj_drop(f);
   return 6;
  }
  b = container_of(n, struct bar, node);
  if (b->data != i) {
   bpf_obj_drop(f);
   bpf_obj_drop(b);
   return 7;
  }
  bpf_obj_drop(b);
 }
 bpf_spin_lock(&f->lock);
 n = bpf_list_pop_front(&f->head);
 bpf_spin_unlock(&f->lock);
 if (n) {
  bpf_obj_drop(f);
  bpf_obj_drop(container_of(n, struct bar, node));
  return 8;
 }
 bpf_obj_drop(f);
 return 0;
}

static __always_inline
int test_list_push_pop(struct bpf_spin_lock *lock, struct bpf_list_head *head)
{
 int ret;

 ret = list_push_pop(lock, head, false);
 if (ret)
  return ret;
 return list_push_pop(lock, head, true);
}

static __always_inline
int test_list_push_pop_multiple(struct bpf_spin_lock *lock, struct bpf_list_head *head)
{
 int ret;

 ret = list_push_pop_multiple(lock, head, false);
 if (ret)
  return ret;
 return list_push_pop_multiple(lock, head, true);
}

static __always_inline
int test_list_in_list(struct bpf_spin_lock *lock, struct bpf_list_head *head)
{
 int ret;

 ret = list_in_list(lock, head, false);
 if (ret)
  return ret;
 return list_in_list(lock, head, true);
}

SEC("tc")
int map_list_push_pop(void *ctx)
{
 struct map_value *v;

 v = bpf_map_lookup_elem(&array_map, &(int){0});
 if (!v)
  return 1;
 return test_list_push_pop(&v->lock, &v->head);
}

SEC("tc")
int inner_map_list_push_pop(void *ctx)
{
 struct map_value *v;
 void *map;

 map = bpf_map_lookup_elem(&map_of_maps, &(int){0});
 if (!map)
  return 1;
 v = bpf_map_lookup_elem(map, &(int){0});
 if (!v)
  return 1;
 return test_list_push_pop(&v->lock, &v->head);
}

SEC("tc")
int global_list_push_pop(void *ctx)
{
 return test_list_push_pop(&glock, &ghead);
}

SEC("tc")
int global_list_push_pop_nested(void *ctx)
{
 return test_list_push_pop(&ghead_nested.inner.lock, &ghead_nested.inner.head);
}

SEC("tc")
int global_list_array_push_pop(void *ctx)
{
 int r;

 r = test_list_push_pop(&glock_c, &ghead_array[0]);
 if (r)
  return r;

 r = test_list_push_pop(&glock_c, &ghead_array[1]);
 if (r)
  return r;

 /* Arrays with only one element is a special case, being treated
 * just like a bpf_list_head variable by the verifier, not an
 * array.
 */

 return test_list_push_pop(&glock_c, &ghead_array_one[0]);
}

SEC("tc")
int map_list_push_pop_multiple(void *ctx)
{
 struct map_value *v;

 v = bpf_map_lookup_elem(&array_map, &(int){0});
 if (!v)
  return 1;
 return test_list_push_pop_multiple(&v->lock, &v->head);
}

SEC("tc")
int inner_map_list_push_pop_multiple(void *ctx)
{
 struct map_value *v;
 void *map;

 map = bpf_map_lookup_elem(&map_of_maps, &(int){0});
 if (!map)
  return 1;
 v = bpf_map_lookup_elem(map, &(int){0});
 if (!v)
  return 1;
 return test_list_push_pop_multiple(&v->lock, &v->head);
}

SEC("tc")
int global_list_push_pop_multiple(void *ctx)
{
 int ret;

 ret = list_push_pop_multiple(&glock, &ghead, false);
 if (ret)
  return ret;
 return list_push_pop_multiple(&glock, &ghead, true);
}

SEC("tc")
int map_list_in_list(void *ctx)
{
 struct map_value *v;

 v = bpf_map_lookup_elem(&array_map, &(int){0});
 if (!v)
  return 1;
 return test_list_in_list(&v->lock, &v->head);
}

SEC("tc")
int inner_map_list_in_list(void *ctx)
{
 struct map_value *v;
 void *map;

 map = bpf_map_lookup_elem(&map_of_maps, &(int){0});
 if (!map)
  return 1;
 v = bpf_map_lookup_elem(map, &(int){0});
 if (!v)
  return 1;
 return test_list_in_list(&v->lock, &v->head);
}

SEC("tc")
int global_list_in_list(void *ctx)
{
 return test_list_in_list(&glock, &ghead);
}

char _license[] SEC("license") = "GPL";

Messung V0.5
C=95 H=96 G=95

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.