diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-02-09 18:34:08 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-02-09 18:36:24 -0500 |
commit | a104f0407b7f5de54972389ef10e11dd8c525a96 (patch) | |
tree | 07c993aeedb4bfe4a52d6725a689a6b018d2b483 /include/linux | |
parent | abe1c3bc8e116879a258bff2316cfb0586f15fec (diff) |
Update bcachefs sources to ea93c26e98 fixup! bcachefs: We can handle missing btree roots for all alloc btrees
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/kernel.h | 3 | ||||
-rw-r--r-- | include/linux/mean_and_variance.h | 24 | ||||
-rw-r--r-- | include/linux/poison.h | 3 | ||||
-rw-r--r-- | include/linux/prandom.h | 6 | ||||
-rw-r--r-- | include/linux/printbuf.h | 306 | ||||
-rw-r--r-- | include/linux/sched.h | 1 | ||||
-rw-r--r-- | include/linux/seq_buf.h | 153 | ||||
-rw-r--r-- | include/linux/shrinker.h | 4 | ||||
-rw-r--r-- | include/linux/six.h | 53 | ||||
-rw-r--r-- | include/linux/slab.h | 5 | ||||
-rw-r--r-- | include/linux/wait.h | 8 |
11 files changed, 245 insertions, 321 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index b2c1751c..a21b7cc3 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -264,4 +264,7 @@ struct qstr { static inline void dump_stack(void) {} +#define unsafe_memcpy(dst, src, bytes, justification) \ + memcpy(dst, src, bytes) + #endif diff --git a/include/linux/mean_and_variance.h b/include/linux/mean_and_variance.h index b7fa5e96..756eb3d1 100644 --- a/include/linux/mean_and_variance.h +++ b/include/linux/mean_and_variance.h @@ -2,13 +2,35 @@ #ifndef MEAN_AND_VARIANCE_H_ #define MEAN_AND_VARIANCE_H_ +#include <linux/kernel.h> #include <linux/types.h> #include <linux/limits.h> #include <linux/math64.h> -#include <linux/printbuf.h> #define SQRT_U64_MAX 4294967295ULL +/** + * abs - return absolute value of an argument + * @x: the value. If it is unsigned type, it is converted to signed type first. + * char is treated as if it was signed (regardless of whether it really is) + * but the macro's return type is preserved as char. + * + * Return: an absolute value of x. + */ +#define abs(x) __abs_choose_expr(x, long long, \ + __abs_choose_expr(x, long, \ + __abs_choose_expr(x, int, \ + __abs_choose_expr(x, short, \ + __abs_choose_expr(x, char, \ + __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), char), \ + (char)({ signed char __x = (x); __x<0?-__x:__x; }), \ + ((void)0))))))) + +#define __abs_choose_expr(x, type, other) __builtin_choose_expr( \ + __builtin_types_compatible_p(typeof(x), signed type) || \ + __builtin_types_compatible_p(typeof(x), unsigned type), \ + ({ signed type __x = (x); __x < 0 ? -__x : __x; }), other) #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__) diff --git a/include/linux/poison.h b/include/linux/poison.h index d62ef5a6..2d3249eb 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -81,4 +81,7 @@ /********** net/core/page_pool.c **********/ #define PP_SIGNATURE (0x40 + POISON_POINTER_DELTA) +/********** kernel/bpf/ **********/ +#define BPF_PTR_POISON ((void *)(0xeB9FUL + POISON_POINTER_DELTA)) + #endif diff --git a/include/linux/prandom.h b/include/linux/prandom.h index 6f177cdd..9aea22dc 100644 --- a/include/linux/prandom.h +++ b/include/linux/prandom.h @@ -23,5 +23,11 @@ prandom_type(u32); prandom_type(u64); #undef prandom_type +static inline u32 prandom_u32_max(u32 max) +{ + return prandom_u32() % max; + +} + #endif /* _LINUX_PRANDOM_H */ diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h deleted file mode 100644 index 24e62e56..00000000 --- a/include/linux/printbuf.h +++ /dev/null @@ -1,306 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ -/* Copyright (C) 2022 Kent Overstreet */ - -#ifndef _LINUX_PRINTBUF_H -#define _LINUX_PRINTBUF_H - -/* - * Printbufs: Simple strings for printing to, with optional heap allocation - * - * This code has provisions for use in userspace, to aid in making other code - * portable between kernelspace and userspace. - * - * Basic example: - * struct printbuf buf = PRINTBUF; - * - * prt_printf(&buf, "foo="); - * foo_to_text(&buf, foo); - * printk("%s", buf.buf); - * printbuf_exit(&buf); - * - * Or - * struct printbuf buf = PRINTBUF_EXTERN(char_buf, char_buf_size) - * - * We can now write pretty printers instead of writing code that dumps - * everything to the kernel log buffer, and then those pretty-printers can be - * used by other code that outputs to kernel log, sysfs, debugfs, etc. - * - * Memory allocation: Outputing to a printbuf may allocate memory. This - * allocation is done with GFP_KERNEL, by default: use the newer - * memalloc_*_(save|restore) functions as needed. - * - * Since no equivalent yet exists for GFP_ATOMIC/GFP_NOWAIT, memory allocations - * will be done with GFP_NOWAIT if printbuf->atomic is nonzero. - * - * It's allowed to grab the output buffer and free it later with kfree() instead - * of using printbuf_exit(), if the user just needs a heap allocated string at - * the end. - * - * Memory allocation failures: We don't return errors directly, because on - * memory allocation failure we usually don't want to bail out and unwind - we - * want to print what we've got, on a best-effort basis. But code that does want - * to return -ENOMEM may check printbuf.allocation_failure. - * - * Indenting, tabstops: - * - * To aid is writing multi-line pretty printers spread across multiple - * functions, printbufs track the current indent level. - * - * printbuf_indent_push() and printbuf_indent_pop() increase and decrease the current indent - * level, respectively. - * - * To use tabstops, set printbuf->tabstops[]; they are in units of spaces, from - * start of line. Once set, prt_tab() will output spaces up to the next tabstop. - * prt_tab_rjust() will also advance the current line of text up to the next - * tabstop, but it does so by shifting text since the previous tabstop up to the - * next tabstop - right justifying it. - * - * Make sure you use prt_newline() instead of \n in the format string for indent - * level and tabstops to work corretly. - * - * Output units: printbuf->units exists to tell pretty-printers how to output - * numbers: a raw value (e.g. directly from a superblock field), as bytes, or as - * human readable bytes. prt_units() obeys it. - */ - -#include <linux/kernel.h> -#include <linux/string.h> - -enum printbuf_si { - PRINTBUF_UNITS_2, /* use binary powers of 2^10 */ - PRINTBUF_UNITS_10, /* use powers of 10^3 (standard SI) */ -}; - -#define PRINTBUF_INLINE_TABSTOPS 4 - -struct printbuf { - char *buf; - unsigned size; - unsigned pos; - unsigned last_newline; - unsigned last_field; - unsigned indent; - /* - * If nonzero, allocations will be done with GFP_ATOMIC: - */ - u8 atomic; - bool allocation_failure:1; - bool heap_allocated:1; - enum printbuf_si si_units:1; - bool human_readable_units:1; - bool has_indent_or_tabstops:1; - bool suppress_indent_tabstop_handling:1; - u8 nr_tabstops; - - /* - * Do not modify directly: use printbuf_tabstop_add(), - * printbuf_tabstop_get() - */ - u8 cur_tabstop; - u8 _tabstops[PRINTBUF_INLINE_TABSTOPS]; -}; - -int printbuf_make_room(struct printbuf *, unsigned); -const char *printbuf_str(const struct printbuf *); -void printbuf_exit(struct printbuf *); - -void printbuf_tabstops_reset(struct printbuf *); -void printbuf_tabstop_pop(struct printbuf *); -int printbuf_tabstop_push(struct printbuf *, unsigned); - -void printbuf_indent_add(struct printbuf *, unsigned); -void printbuf_indent_sub(struct printbuf *, unsigned); - -void prt_newline(struct printbuf *); -void prt_tab(struct printbuf *); -void prt_tab_rjust(struct printbuf *); - -void prt_bytes_indented(struct printbuf *, const char *, unsigned); -void prt_human_readable_u64(struct printbuf *, u64); -void prt_human_readable_s64(struct printbuf *, s64); -void prt_units_u64(struct printbuf *, u64); -void prt_units_s64(struct printbuf *, s64); - -/* Initializer for a heap allocated printbuf: */ -#define PRINTBUF ((struct printbuf) { .heap_allocated = true }) - -/* Initializer a printbuf that points to an external buffer: */ -#define PRINTBUF_EXTERN(_buf, _size) \ -((struct printbuf) { \ - .buf = _buf, \ - .size = _size, \ -}) - -/* - * Returns size remaining of output buffer: - */ -static inline unsigned printbuf_remaining_size(struct printbuf *out) -{ - return out->pos < out->size ? out->size - out->pos : 0; -} - -/* - * Returns number of characters we can print to the output buffer - i.e. - * excluding the terminating nul: - */ -static inline unsigned printbuf_remaining(struct printbuf *out) -{ - return out->pos < out->size ? out->size - out->pos - 1 : 0; -} - -static inline unsigned printbuf_written(struct printbuf *out) -{ - return out->size ? min(out->pos, out->size - 1) : 0; -} - -/* - * Returns true if output was truncated: - */ -static inline bool printbuf_overflowed(struct printbuf *out) -{ - return out->pos >= out->size; -} - -static inline void printbuf_nul_terminate(struct printbuf *out) -{ - printbuf_make_room(out, 1); - - if (out->pos < out->size) - out->buf[out->pos] = 0; - else if (out->size) - out->buf[out->size - 1] = 0; -} - -/* Doesn't call printbuf_make_room(), doesn't nul terminate: */ -static inline void __prt_char_reserved(struct printbuf *out, char c) -{ - if (printbuf_remaining(out)) - out->buf[out->pos] = c; - out->pos++; -} - -/* Doesn't nul terminate: */ -static inline void __prt_char(struct printbuf *out, char c) -{ - printbuf_make_room(out, 1); - __prt_char_reserved(out, c); -} - -static inline void prt_char(struct printbuf *out, char c) -{ - __prt_char(out, c); - printbuf_nul_terminate(out); -} - -static inline void __prt_chars_reserved(struct printbuf *out, char c, unsigned n) -{ - unsigned i, can_print = min(n, printbuf_remaining(out)); - - for (i = 0; i < can_print; i++) - out->buf[out->pos++] = c; - out->pos += n - can_print; -} - -static inline void prt_chars(struct printbuf *out, char c, unsigned n) -{ - printbuf_make_room(out, n); - __prt_chars_reserved(out, c, n); - printbuf_nul_terminate(out); -} - -static inline void prt_bytes(struct printbuf *out, const void *b, unsigned n) -{ - unsigned i, can_print; - - printbuf_make_room(out, n); - - can_print = min(n, printbuf_remaining(out)); - - for (i = 0; i < can_print; i++) - out->buf[out->pos++] = ((char *) b)[i]; - out->pos += n - can_print; - - printbuf_nul_terminate(out); -} - -static inline void prt_str(struct printbuf *out, const char *str) -{ - prt_bytes(out, str, strlen(str)); -} - -static inline void prt_str_indented(struct printbuf *out, const char *str) -{ - prt_bytes_indented(out, str, strlen(str)); -} - -static inline void prt_hex_byte(struct printbuf *out, u8 byte) -{ - printbuf_make_room(out, 2); - __prt_char_reserved(out, hex_asc_hi(byte)); - __prt_char_reserved(out, hex_asc_lo(byte)); - printbuf_nul_terminate(out); -} - -static inline void prt_hex_byte_upper(struct printbuf *out, u8 byte) -{ - printbuf_make_room(out, 2); - __prt_char_reserved(out, hex_asc_upper_hi(byte)); - __prt_char_reserved(out, hex_asc_upper_lo(byte)); - printbuf_nul_terminate(out); -} - -/** - * printbuf_reset - re-use a printbuf without freeing and re-initializing it: - */ -static inline void printbuf_reset(struct printbuf *buf) -{ - buf->pos = 0; - buf->allocation_failure = 0; - buf->indent = 0; - buf->nr_tabstops = 0; - buf->cur_tabstop = 0; -} - -/** - * printbuf_atomic_inc - mark as entering an atomic section - */ -static inline void printbuf_atomic_inc(struct printbuf *buf) -{ - buf->atomic++; -} - -/** - * printbuf_atomic_inc - mark as leaving an atomic section - */ -static inline void printbuf_atomic_dec(struct printbuf *buf) -{ - buf->atomic--; -} - -/* - * This is used for the %pf(%p) sprintf format extension, where we pass a pretty - * printer and arguments to the pretty-printer to sprintf - * - * Instead of passing a pretty-printer function to sprintf directly, we pass it - * a pointer to a struct call_pp, so that sprintf can check that the magic - * number is present, which in turn ensures that the CALL_PP() macro has been - * used in order to typecheck the arguments to the pretty printer function - * - * Example usage: - * sprintf("%pf(%p)", CALL_PP(prt_bdev, bdev)); - */ -struct call_pp { - unsigned long magic; - void *fn; -}; - -#define PP_TYPECHECK(fn, ...) \ - ({ while (0) fn((struct printbuf *) NULL, ##__VA_ARGS__); }) - -#define CALL_PP_MAGIC (unsigned long) 0xce0b92d22f6b6be4 - -#define CALL_PP(fn, ...) \ - (PP_TYPECHECK(fn, ##__VA_ARGS__), \ - &((struct call_pp) { CALL_PP_MAGIC, fn })), ##__VA_ARGS__ - -#endif /* _LINUX_PRINTBUF_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index ac6d27bb..fef7e323 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -28,6 +28,7 @@ #define TASK_NEW 2048 #define TASK_IDLE_WORKER 4096 #define TASK_STATE_MAX 8192 +#define TASK_FREEZABLE (1U << 14) /* Convenience macros for the sake of set_task_state */ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h new file mode 100644 index 00000000..8c9c0dd7 --- /dev/null +++ b/include/linux/seq_buf.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_SEQ_BUF_H +#define _LINUX_SEQ_BUF_H + +#include <linux/kernel.h> +#include <stdarg.h> +#include <string.h> + +/* + * Trace sequences are used to allow a function to call several other functions + * to create a string of data to use. + */ + +/** + * seq_buf - seq buffer structure + * @buffer: pointer to the buffer + * @size: size of the buffer + * @len: the amount of data inside the buffer + * @readpos: The next position to read in the buffer. + */ +struct seq_buf { + char *buffer; + size_t size; + size_t len; + loff_t readpos; +}; + +static inline void seq_buf_clear(struct seq_buf *s) +{ + s->len = 0; + s->readpos = 0; +} + +static inline void +seq_buf_init(struct seq_buf *s, char *buf, unsigned int size) +{ + s->buffer = buf; + s->size = size; + seq_buf_clear(s); +} + +/* + * seq_buf have a buffer that might overflow. When this happens + * the len and size are set to be equal. + */ +static inline bool +seq_buf_has_overflowed(struct seq_buf *s) +{ + return s->len > s->size; +} + +static inline void +seq_buf_set_overflow(struct seq_buf *s) +{ + s->len = s->size + 1; +} + +/* + * How much buffer is left on the seq_buf? + */ +static inline unsigned int +seq_buf_buffer_left(struct seq_buf *s) +{ + if (seq_buf_has_overflowed(s)) + return 0; + + return s->size - s->len; +} + +/* How much buffer was written? */ +static inline unsigned int seq_buf_used(struct seq_buf *s) +{ + return min(s->len, s->size); +} + +/** + * seq_buf_terminate - Make sure buffer is nul terminated + * @s: the seq_buf descriptor to terminate. + * + * This makes sure that the buffer in @s is nul terminated and + * safe to read as a string. + * + * Note, if this is called when the buffer has overflowed, then + * the last byte of the buffer is zeroed, and the len will still + * point passed it. + * + * After this function is called, s->buffer is safe to use + * in string operations. + */ +static inline void seq_buf_terminate(struct seq_buf *s) +{ + if (WARN_ON(s->size == 0)) + return; + + if (seq_buf_buffer_left(s)) + s->buffer[s->len] = 0; + else + s->buffer[s->size - 1] = 0; +} + +/** + * seq_buf_get_buf - get buffer to write arbitrary data to + * @s: the seq_buf handle + * @bufp: the beginning of the buffer is stored here + * + * Return the number of bytes available in the buffer, or zero if + * there's no space. + */ +static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp) +{ + WARN_ON(s->len > s->size + 1); + + if (s->len < s->size) { + *bufp = s->buffer + s->len; + return s->size - s->len; + } + + *bufp = NULL; + return 0; +} + +/** + * seq_buf_commit - commit data to the buffer + * @s: the seq_buf handle + * @num: the number of bytes to commit + * + * Commit @num bytes of data written to a buffer previously acquired + * by seq_buf_get. To signal an error condition, or that the data + * didn't fit in the available space, pass a negative @num value. + */ +static inline void seq_buf_commit(struct seq_buf *s, int num) +{ + if (num < 0) { + seq_buf_set_overflow(s); + } else { + /* num must be negative on overflow */ + BUG_ON(s->len + num > s->size); + s->len += num; + } +} + +extern __printf(2, 3) +int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); +extern __printf(2, 0) +int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); +extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, + int cnt); +extern int seq_buf_puts(struct seq_buf *s, const char *str); +extern int seq_buf_putc(struct seq_buf *s, unsigned char c); + +void seq_buf_human_readable_u64(struct seq_buf *, u64); + +#endif /* _LINUX_SEQ_BUF_H */ diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index ebbab7a6..bca00d61 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -11,13 +11,13 @@ struct shrink_control { #define SHRINK_STOP (~0UL) -struct printbuf; +struct seq_buf; struct shrinker { unsigned long (*count_objects)(struct shrinker *, struct shrink_control *sc); unsigned long (*scan_objects)(struct shrinker *, struct shrink_control *sc); - void (*to_text)(struct printbuf *, struct shrinker *); + void (*to_text)(struct seq_buf *, struct shrinker *); int seeks; /* seeks to recreate an obj */ long batch; /* reclaim batch size, 0 = default */ diff --git a/include/linux/six.h b/include/linux/six.h index 362a577b..16ad2073 100644 --- a/include/linux/six.h +++ b/include/linux/six.h @@ -59,6 +59,7 @@ */ #include <linux/lockdep.h> +#include <linux/osq_lock.h> #include <linux/sched.h> #include <linux/types.h> @@ -79,9 +80,10 @@ union six_lock_state { }; struct { - unsigned read_lock:27; + unsigned read_lock:26; unsigned write_locking:1; unsigned intent_lock:1; + unsigned nospin:1; unsigned waiters:3; /* * seq works much like in seqlocks: it's incremented every time @@ -104,10 +106,10 @@ enum six_lock_type { struct six_lock { union six_lock_state state; + unsigned intent_lock_recurse; struct task_struct *owner; unsigned __percpu *readers; - unsigned intent_lock_recurse; - unsigned long ip; + struct optimistic_spin_queue osq; raw_spinlock_t wait_lock; struct list_head wait_list; #ifdef CONFIG_DEBUG_LOCK_ALLOC @@ -148,12 +150,37 @@ do { \ #define __SIX_VAL(field, _v) (((union six_lock_state) { .field = _v }).v) #define __SIX_LOCK(type) \ -bool six_trylock_##type(struct six_lock *); \ -bool six_relock_##type(struct six_lock *, u32); \ -int six_lock_##type(struct six_lock *, six_lock_should_sleep_fn, void *);\ -int six_lock_waiter_##type(struct six_lock *, struct six_lock_waiter *, \ - six_lock_should_sleep_fn, void *); \ -void six_unlock_##type(struct six_lock *); +bool six_trylock_ip_##type(struct six_lock *, unsigned long); \ +bool six_relock_ip_##type(struct six_lock *, u32, unsigned long); \ +int six_lock_ip_##type(struct six_lock *, six_lock_should_sleep_fn, \ + void *, unsigned long); \ +int six_lock_ip_waiter_##type(struct six_lock *, struct six_lock_waiter *,\ + six_lock_should_sleep_fn, void *, unsigned long);\ +void six_unlock_ip_##type(struct six_lock *, unsigned long); \ + \ +static inline bool six_trylock_##type(struct six_lock *lock) \ +{ \ + return six_trylock_ip_##type(lock, _THIS_IP_); \ +} \ +static inline bool six_relock_##type(struct six_lock *lock, u32 seq) \ +{ \ + return six_relock_ip_##type(lock, seq, _THIS_IP_); \ +} \ +static inline int six_lock_##type(struct six_lock *lock, \ + six_lock_should_sleep_fn fn, void *p)\ +{ \ + return six_lock_ip_##type(lock, fn, p, _THIS_IP_); \ +} \ +static inline int six_lock_waiter_##type(struct six_lock *lock, \ + struct six_lock_waiter *wait, \ + six_lock_should_sleep_fn fn, void *p) \ +{ \ + return six_lock_ip_waiter_##type(lock, wait, fn, p, _THIS_IP_); \ +} \ +static inline void six_unlock_##type(struct six_lock *lock) \ +{ \ + return six_unlock_ip_##type(lock, _THIS_IP_); \ +} __SIX_LOCK(read) __SIX_LOCK(intent) @@ -189,6 +216,14 @@ static inline int six_lock_type(struct six_lock *lock, enum six_lock_type type, SIX_LOCK_DISPATCH(type, six_lock, lock, should_sleep_fn, p); } +static inline int six_lock_type_ip_waiter(struct six_lock *lock, enum six_lock_type type, + struct six_lock_waiter *wait, + six_lock_should_sleep_fn should_sleep_fn, void *p, + unsigned long ip) +{ + SIX_LOCK_DISPATCH(type, six_lock_ip_waiter, lock, wait, should_sleep_fn, p, ip); +} + static inline int six_lock_type_waiter(struct six_lock *lock, enum six_lock_type type, struct six_lock_waiter *wait, six_lock_should_sleep_fn should_sleep_fn, void *p) diff --git a/include/linux/slab.h b/include/linux/slab.h index cf48570c..ff122ff9 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -174,6 +174,11 @@ static inline void *kmem_cache_alloc(struct kmem_cache *c, gfp_t gfp) return kmalloc(c->obj_size, gfp); } +static inline void *kmem_cache_zalloc(struct kmem_cache *c, gfp_t gfp) +{ + return kzalloc(c->obj_size, gfp); +} + static inline void kmem_cache_free(struct kmem_cache *c, void *p) { kfree(p); diff --git a/include/linux/wait.h b/include/linux/wait.h index d30fb10d..4b9cbf38 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -18,10 +18,12 @@ struct __wait_queue { struct list_head task_list; }; -typedef struct { +struct wait_queue_head { spinlock_t lock; struct list_head task_list; -} wait_queue_head_t; +}; + +typedef struct wait_queue_head wait_queue_head_t; void wake_up(wait_queue_head_t *); void wake_up_all(wait_queue_head_t *); @@ -42,7 +44,7 @@ int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *ke .task_list = { &(name).task_list, &(name).task_list } } #define DECLARE_WAIT_QUEUE_HEAD(name) \ - wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) + struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name) static inline void init_waitqueue_head(wait_queue_head_t *q) { |