cache.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /* Copyright (C) 2024 Intel Corporation */
  3. #ifndef __LIBETH_CACHE_H
  4. #define __LIBETH_CACHE_H
  5. #include <linux/cache.h>
  6. /**
  7. * libeth_cacheline_group_assert - make sure cacheline group size is expected
  8. * @type: type of the structure containing the group
  9. * @grp: group name inside the struct
  10. * @sz: expected group size
  11. */
  12. #if defined(CONFIG_64BIT) && SMP_CACHE_BYTES == 64
  13. #define libeth_cacheline_group_assert(type, grp, sz) \
  14. static_assert(offsetof(type, __cacheline_group_end__##grp) - \
  15. offsetofend(type, __cacheline_group_begin__##grp) == \
  16. (sz))
  17. #define __libeth_cacheline_struct_assert(type, sz) \
  18. static_assert(sizeof(type) == (sz))
  19. #else /* !CONFIG_64BIT || SMP_CACHE_BYTES != 64 */
  20. #define libeth_cacheline_group_assert(type, grp, sz) \
  21. static_assert(offsetof(type, __cacheline_group_end__##grp) - \
  22. offsetofend(type, __cacheline_group_begin__##grp) <= \
  23. (sz))
  24. #define __libeth_cacheline_struct_assert(type, sz) \
  25. static_assert(sizeof(type) <= (sz))
  26. #endif /* !CONFIG_64BIT || SMP_CACHE_BYTES != 64 */
  27. #define __libeth_cls1(sz1) SMP_CACHE_ALIGN(sz1)
  28. #define __libeth_cls2(sz1, sz2) (SMP_CACHE_ALIGN(sz1) + SMP_CACHE_ALIGN(sz2))
  29. #define __libeth_cls3(sz1, sz2, sz3) \
  30. (SMP_CACHE_ALIGN(sz1) + SMP_CACHE_ALIGN(sz2) + SMP_CACHE_ALIGN(sz3))
  31. #define __libeth_cls(...) \
  32. CONCATENATE(__libeth_cls, COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)
  33. /**
  34. * libeth_cacheline_struct_assert - make sure CL-based struct size is expected
  35. * @type: type of the struct
  36. * @...: from 1 to 3 CL group sizes (read-mostly, read-write, cold)
  37. *
  38. * When a struct contains several CL groups, it's difficult to predict its size
  39. * on different architectures. The macro instead takes sizes of all of the
  40. * groups the structure contains and generates the final struct size.
  41. */
  42. #define libeth_cacheline_struct_assert(type, ...) \
  43. __libeth_cacheline_struct_assert(type, __libeth_cls(__VA_ARGS__)); \
  44. static_assert(__alignof(type) >= SMP_CACHE_BYTES)
  45. /**
  46. * libeth_cacheline_set_assert - make sure CL-based struct layout is expected
  47. * @type: type of the struct
  48. * @ro: expected size of the read-mostly group
  49. * @rw: expected size of the read-write group
  50. * @c: expected size of the cold group
  51. *
  52. * Check that each group size is expected and then do final struct size check.
  53. */
  54. #define libeth_cacheline_set_assert(type, ro, rw, c) \
  55. libeth_cacheline_group_assert(type, read_mostly, ro); \
  56. libeth_cacheline_group_assert(type, read_write, rw); \
  57. libeth_cacheline_group_assert(type, cold, c); \
  58. libeth_cacheline_struct_assert(type, ro, rw, c)
  59. #endif /* __LIBETH_CACHE_H */