linux/include/linux/flex_array.h
<<
>>
Prefs
   1#ifndef _FLEX_ARRAY_H
   2#define _FLEX_ARRAY_H
   3
   4#include <linux/types.h>
   5#include <asm/page.h>
   6
   7#define FLEX_ARRAY_PART_SIZE PAGE_SIZE
   8#define FLEX_ARRAY_BASE_SIZE PAGE_SIZE
   9
  10struct flex_array_part;
  11
  12/*
  13 * This is meant to replace cases where an array-like
  14 * structure has gotten too big to fit into kmalloc()
  15 * and the developer is getting tempted to use
  16 * vmalloc().
  17 */
  18
  19struct flex_array {
  20        union {
  21                struct {
  22                        int element_size;
  23                        int total_nr_elements;
  24                        struct flex_array_part *parts[];
  25                };
  26                /*
  27                 * This little trick makes sure that
  28                 * sizeof(flex_array) == PAGE_SIZE
  29                 */
  30                char padding[FLEX_ARRAY_BASE_SIZE];
  31        };
  32};
  33
  34/* Number of bytes left in base struct flex_array, excluding metadata */
  35#define FLEX_ARRAY_BASE_BYTES_LEFT                                      \
  36        (FLEX_ARRAY_BASE_SIZE - offsetof(struct flex_array, parts))
  37
  38/* Number of pointers in base to struct flex_array_part pages */
  39#define FLEX_ARRAY_NR_BASE_PTRS                                         \
  40        (FLEX_ARRAY_BASE_BYTES_LEFT / sizeof(struct flex_array_part *))
  41
  42/* Number of elements of size that fit in struct flex_array_part */
  43#define FLEX_ARRAY_ELEMENTS_PER_PART(size)                              \
  44        (FLEX_ARRAY_PART_SIZE / size)
  45
  46/*
  47 * Defines a statically allocated flex array and ensures its parameters are
  48 * valid.
  49 */
  50#define DEFINE_FLEX_ARRAY(__arrayname, __element_size, __total)         \
  51        struct flex_array __arrayname = { { {                           \
  52                .element_size = (__element_size),                       \
  53                .total_nr_elements = (__total),                         \
  54        } } };                                                          \
  55        static inline void __arrayname##_invalid_parameter(void)        \
  56        {                                                               \
  57                BUILD_BUG_ON((__total) > FLEX_ARRAY_NR_BASE_PTRS *      \
  58                        FLEX_ARRAY_ELEMENTS_PER_PART(__element_size));  \
  59        }
  60
  61struct flex_array *flex_array_alloc(int element_size, unsigned int total,
  62                gfp_t flags);
  63int flex_array_prealloc(struct flex_array *fa, unsigned int start,
  64                unsigned int end, gfp_t flags);
  65void flex_array_free(struct flex_array *fa);
  66void flex_array_free_parts(struct flex_array *fa);
  67int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
  68                gfp_t flags);
  69int flex_array_clear(struct flex_array *fa, unsigned int element_nr);
  70void *flex_array_get(struct flex_array *fa, unsigned int element_nr);
  71int flex_array_shrink(struct flex_array *fa);
  72
  73#endif /* _FLEX_ARRAY_H */
  74