mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 09:12:07 +00:00
XArray: Add extra debugging check to xas_lock and friends
While tracking down a recent bug, we discovered somewhere that had forgotten to call xas_reset() before calling xas_lock(). Add a debug check to be sure that doesn't happen in future. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
This commit is contained in:
parent
c88414f56c
commit
6684aba078
@ -1407,16 +1407,44 @@ struct xa_state {
|
||||
order - (order % XA_CHUNK_SHIFT), \
|
||||
(1U << (order % XA_CHUNK_SHIFT)) - 1)
|
||||
|
||||
/**
|
||||
* xas_invalid() - Is the xas in a retry or error state?
|
||||
* @xas: XArray operation state.
|
||||
*
|
||||
* Return: %true if the xas cannot be used for operations.
|
||||
*/
|
||||
static inline bool xas_invalid(const struct xa_state *xas)
|
||||
{
|
||||
return (unsigned long)xas->xa_node & 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* xas_valid() - Is the xas a valid cursor into the array?
|
||||
* @xas: XArray operation state.
|
||||
*
|
||||
* Return: %true if the xas can be used for operations.
|
||||
*/
|
||||
static inline bool xas_valid(const struct xa_state *xas)
|
||||
{
|
||||
return !xas_invalid(xas);
|
||||
}
|
||||
|
||||
static inline struct xa_state *XAS_INVALID(struct xa_state *xas)
|
||||
{
|
||||
XA_NODE_BUG_ON(xas->xa_node, xas_valid(xas));
|
||||
return xas;
|
||||
}
|
||||
|
||||
#define xas_marked(xas, mark) xa_marked((xas)->xa, (mark))
|
||||
#define xas_trylock(xas) xa_trylock((xas)->xa)
|
||||
#define xas_lock(xas) xa_lock((xas)->xa)
|
||||
#define xas_trylock(xas) xa_trylock(XAS_INVALID(xas)->xa)
|
||||
#define xas_lock(xas) xa_lock(XAS_INVALID(xas)->xa)
|
||||
#define xas_unlock(xas) xa_unlock((xas)->xa)
|
||||
#define xas_lock_bh(xas) xa_lock_bh((xas)->xa)
|
||||
#define xas_lock_bh(xas) xa_lock_bh(XAS_INVALID(xas)->xa)
|
||||
#define xas_unlock_bh(xas) xa_unlock_bh((xas)->xa)
|
||||
#define xas_lock_irq(xas) xa_lock_irq((xas)->xa)
|
||||
#define xas_lock_irq(xas) xa_lock_irq(XAS_INVALID(xas)->xa)
|
||||
#define xas_unlock_irq(xas) xa_unlock_irq((xas)->xa)
|
||||
#define xas_lock_irqsave(xas, flags) \
|
||||
xa_lock_irqsave((xas)->xa, flags)
|
||||
xa_lock_irqsave(XAS_INVALID(xas)->xa, flags)
|
||||
#define xas_unlock_irqrestore(xas, flags) \
|
||||
xa_unlock_irqrestore((xas)->xa, flags)
|
||||
|
||||
@ -1445,28 +1473,6 @@ static inline void xas_set_err(struct xa_state *xas, long err)
|
||||
xas->xa_node = XA_ERROR(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* xas_invalid() - Is the xas in a retry or error state?
|
||||
* @xas: XArray operation state.
|
||||
*
|
||||
* Return: %true if the xas cannot be used for operations.
|
||||
*/
|
||||
static inline bool xas_invalid(const struct xa_state *xas)
|
||||
{
|
||||
return (unsigned long)xas->xa_node & 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* xas_valid() - Is the xas a valid cursor into the array?
|
||||
* @xas: XArray operation state.
|
||||
*
|
||||
* Return: %true if the xas can be used for operations.
|
||||
*/
|
||||
static inline bool xas_valid(const struct xa_state *xas)
|
||||
{
|
||||
return !xas_invalid(xas);
|
||||
}
|
||||
|
||||
/**
|
||||
* xas_is_node() - Does the xas point to a node?
|
||||
* @xas: XArray operation state.
|
||||
|
@ -2243,7 +2243,6 @@ void xa_destroy(struct xarray *xa)
|
||||
unsigned long flags;
|
||||
void *entry;
|
||||
|
||||
xas.xa_node = NULL;
|
||||
xas_lock_irqsave(&xas, flags);
|
||||
entry = xa_head_locked(xa);
|
||||
RCU_INIT_POINTER(xa->xa_head, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user