Skip to content

Commit

Permalink
maple_tree: Be more strict about locking
Browse files Browse the repository at this point in the history
Use lockdep to check the write path in the maple tree holds the lock in
write mode.

Introduce mt_write_lock_is_held() to check if the lock is held for
writing.  Update the necessary checks for rcu_dereference_protected() to
use the new write lock check.

Link: https://lkml.kernel.org/r/20230714195551.894800-5-Liam.Howlett@oracle.com
Signed-off-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oliver Sang <oliver.sang@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
  • Loading branch information
Liam R. Howlett authored and Andrew Morton committed Aug 18, 2023
1 parent 02fdb25 commit 19a462f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 3 deletions.
7 changes: 6 additions & 1 deletion include/linux/maple_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,18 @@ typedef struct lockdep_map *lockdep_map_p;
#define mt_lock_is_held(mt) \
(!(mt)->ma_external_lock || lock_is_held((mt)->ma_external_lock))

#define mt_write_lock_is_held(mt) \
(!(mt)->ma_external_lock || \
lock_is_held_type((mt)->ma_external_lock, 0))

#define mt_set_external_lock(mt, lock) \
(mt)->ma_external_lock = &(lock)->dep_map

#define mt_on_stack(mt) (mt).ma_external_lock = NULL
#else
typedef struct { /* nothing */ } lockdep_map_p;
#define mt_lock_is_held(mt) 1
#define mt_lock_is_held(mt) 1
#define mt_write_lock_is_held(mt) 1
#define mt_set_external_lock(mt, lock) do { } while (0)
#define mt_on_stack(mt) do { } while (0)
#endif
Expand Down
10 changes: 8 additions & 2 deletions lib/maple_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,12 @@ static inline void __rcu **ma_slots(struct maple_node *mn, enum maple_type mt)
}
}

static inline bool mt_write_locked(const struct maple_tree *mt)
{
return mt_external_lock(mt) ? mt_write_lock_is_held(mt) :
lockdep_is_held(&mt->ma_lock);
}

static inline bool mt_locked(const struct maple_tree *mt)
{
return mt_external_lock(mt) ? mt_lock_is_held(mt) :
Expand All @@ -792,7 +798,7 @@ static inline void *mt_slot(const struct maple_tree *mt,
static inline void *mt_slot_locked(struct maple_tree *mt, void __rcu **slots,
unsigned char offset)
{
return rcu_dereference_protected(slots[offset], mt_locked(mt));
return rcu_dereference_protected(slots[offset], mt_write_locked(mt));
}
/*
* mas_slot_locked() - Get the slot value when holding the maple tree lock.
Expand Down Expand Up @@ -835,7 +841,7 @@ static inline void *mas_root(struct ma_state *mas)

static inline void *mt_root_locked(struct maple_tree *mt)
{
return rcu_dereference_protected(mt->ma_root, mt_locked(mt));
return rcu_dereference_protected(mt->ma_root, mt_write_locked(mt));
}

/*
Expand Down

0 comments on commit 19a462f

Please sign in to comment.