bpf_util.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __BPF_UTIL__
  3. #define __BPF_UTIL__
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <syscall.h>
  9. #include <bpf/libbpf.h> /* libbpf_num_possible_cpus */
  10. static inline unsigned int bpf_num_possible_cpus(void)
  11. {
  12. int possible_cpus = libbpf_num_possible_cpus();
  13. if (possible_cpus < 0) {
  14. printf("Failed to get # of possible cpus: '%s'!\n",
  15. strerror(-possible_cpus));
  16. exit(1);
  17. }
  18. return possible_cpus;
  19. }
  20. /* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst
  21. * is zero-terminated string no matter what (unless sz == 0, in which case
  22. * it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs
  23. * in what is returned. Given this is internal helper, it's trivial to extend
  24. * this, when necessary. Use this instead of strncpy inside libbpf source code.
  25. */
  26. static inline void bpf_strlcpy(char *dst, const char *src, size_t sz)
  27. {
  28. size_t i;
  29. if (sz == 0)
  30. return;
  31. sz--;
  32. for (i = 0; i < sz && src[i]; i++)
  33. dst[i] = src[i];
  34. dst[i] = '\0';
  35. }
  36. #define __bpf_percpu_val_align __attribute__((__aligned__(8)))
  37. #define BPF_DECLARE_PERCPU(type, name) \
  38. struct { type v; /* padding */ } __bpf_percpu_val_align \
  39. name[bpf_num_possible_cpus()]
  40. #define bpf_percpu(name, cpu) name[(cpu)].v
  41. #ifndef ARRAY_SIZE
  42. # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  43. #endif
  44. #ifndef sizeof_field
  45. #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER))
  46. #endif
  47. #ifndef offsetofend
  48. #define offsetofend(TYPE, MEMBER) \
  49. (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
  50. #endif
  51. /* Availability of gettid across glibc versions is hit-and-miss, therefore
  52. * fallback to syscall in this macro and use it everywhere.
  53. */
  54. #ifndef sys_gettid
  55. #define sys_gettid() syscall(SYS_gettid)
  56. #endif
  57. #endif /* __BPF_UTIL__ */