Commit 02669b17 authored by Matthew Wilcox's avatar Matthew Wilcox
Browse files

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: default avatarMatthew Wilcox <willy@infradead.org>
parent 490fd30f
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -286,7 +286,6 @@ struct xarray {
 */
#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_store(struct xarray *, unsigned long index, void *entry, gfp_t);
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);
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: XArray.
+0 −29
Original line number Diff line number Diff line
@@ -1250,35 +1250,6 @@ void *xas_find_conflict(struct xa_state *xas)
}
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: XArray.