mirror of
https://github.com/torvalds/linux
synced 2024-10-15 15:59:15 +00:00
XArray: Turn xa_init_flags into a static inline
A regular xa_init_flags() put all dynamically-initialised XArrays into the same locking class. That leads to lockdep believing that taking one XArray lock while holding another is a deadlock. It's possible to work around some of these situations with separate locking classes for irq/bh/regular XArrays, and SINGLE_DEPTH_NESTING, but that's ugly, and it doesn't work for all situations (where we have completely unrelated XArrays). Signed-off-by: Matthew Wilcox <willy@infradead.org>
This commit is contained in:
parent
490fd30f85
commit
02669b17a4
|
@ -286,7 +286,6 @@ struct xarray {
|
||||||
*/
|
*/
|
||||||
#define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC)
|
#define DEFINE_XARRAY_ALLOC(name) DEFINE_XARRAY_FLAGS(name, XA_FLAGS_ALLOC)
|
||||||
|
|
||||||
void xa_init_flags(struct xarray *, gfp_t flags);
|
|
||||||
void *xa_load(struct xarray *, unsigned long index);
|
void *xa_load(struct xarray *, unsigned long index);
|
||||||
void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
|
void *xa_store(struct xarray *, unsigned long index, void *entry, gfp_t);
|
||||||
void *xa_erase(struct xarray *, unsigned long index);
|
void *xa_erase(struct xarray *, unsigned long index);
|
||||||
|
@ -303,6 +302,24 @@ unsigned int xa_extract(struct xarray *, void **dst, unsigned long start,
|
||||||
unsigned long max, unsigned int n, xa_mark_t);
|
unsigned long max, unsigned int n, xa_mark_t);
|
||||||
void xa_destroy(struct xarray *);
|
void xa_destroy(struct xarray *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xa_init_flags() - Initialise an empty XArray with flags.
|
||||||
|
* @xa: XArray.
|
||||||
|
* @flags: XA_FLAG values.
|
||||||
|
*
|
||||||
|
* If you need to initialise an XArray with special flags (eg you need
|
||||||
|
* to take the lock from interrupt context), use this function instead
|
||||||
|
* of xa_init().
|
||||||
|
*
|
||||||
|
* Context: Any context.
|
||||||
|
*/
|
||||||
|
static inline void xa_init_flags(struct xarray *xa, gfp_t flags)
|
||||||
|
{
|
||||||
|
spin_lock_init(&xa->xa_lock);
|
||||||
|
xa->xa_flags = flags;
|
||||||
|
xa->xa_head = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xa_init() - Initialise an empty XArray.
|
* xa_init() - Initialise an empty XArray.
|
||||||
* @xa: XArray.
|
* @xa: XArray.
|
||||||
|
|
29
lib/xarray.c
29
lib/xarray.c
|
@ -1250,35 +1250,6 @@ void *xas_find_conflict(struct xa_state *xas)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xas_find_conflict);
|
EXPORT_SYMBOL_GPL(xas_find_conflict);
|
||||||
|
|
||||||
/**
|
|
||||||
* xa_init_flags() - Initialise an empty XArray with flags.
|
|
||||||
* @xa: XArray.
|
|
||||||
* @flags: XA_FLAG values.
|
|
||||||
*
|
|
||||||
* If you need to initialise an XArray with special flags (eg you need
|
|
||||||
* to take the lock from interrupt context), use this function instead
|
|
||||||
* of xa_init().
|
|
||||||
*
|
|
||||||
* Context: Any context.
|
|
||||||
*/
|
|
||||||
void xa_init_flags(struct xarray *xa, gfp_t flags)
|
|
||||||
{
|
|
||||||
unsigned int lock_type;
|
|
||||||
static struct lock_class_key xa_lock_irq;
|
|
||||||
static struct lock_class_key xa_lock_bh;
|
|
||||||
|
|
||||||
spin_lock_init(&xa->xa_lock);
|
|
||||||
xa->xa_flags = flags;
|
|
||||||
xa->xa_head = NULL;
|
|
||||||
|
|
||||||
lock_type = xa_lock_type(xa);
|
|
||||||
if (lock_type == XA_LOCK_IRQ)
|
|
||||||
lockdep_set_class(&xa->xa_lock, &xa_lock_irq);
|
|
||||||
else if (lock_type == XA_LOCK_BH)
|
|
||||||
lockdep_set_class(&xa->xa_lock, &xa_lock_bh);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(xa_init_flags);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xa_load() - Load an entry from an XArray.
|
* xa_load() - Load an entry from an XArray.
|
||||||
* @xa: XArray.
|
* @xa: XArray.
|
||||||
|
|
Loading…
Reference in a new issue