[PATCH] * dlm: improve lock management and concurrency control

Alessio Attilio posted 1 patch 4 months, 4 weeks ago
fs/dlm/lock.c | 99 ++++++++++++++++++++++++---------------------------
1 file changed, 46 insertions(+), 53 deletions(-)
[PATCH] * dlm: improve lock management and concurrency control
Posted by Alessio Attilio 4 months, 4 weeks ago
From: Alessio Attilio <alessio.attilio@engineer.com>

This patch introduces several improvements to lock handling in the DLM
subsystem, focusing on thread safety, correctness, and code clarity.

- Added explicit locking (spin_lock_bh/spin_unlock_bh) around accesses
  to proc->locks and proc->asts in dlm_clear_proc_locks, ensuring safe
  concurrent operations during lock cleanup.
- Replaced del_proc_lock with direct, lock-protected list operations
  for improved clarity and correctness.
- Updated send_unlock to set RSB_MASTER_UNCERTAIN only when releasing
  the last lock on an rsb, ensuring proper master confirmation.
- Improved handling of persistent and non-persistent locks by setting
  appropriate flags (DLM_DFL_ORPHAN_BIT or DLM_IFL_DEAD_BIT) before
  orphaning or unlocking.
- Removed outdated comments related to mutex protection and serialization
  assumptions, reflecting the updated concurrency model.

Signed-off-by: Alessio Attilio <alessio.attilio.dev@gmail.com>
---
 fs/dlm/lock.c | 99 ++++++++++++++++++++++++---------------------------
 1 file changed, 46 insertions(+), 53 deletions(-)

diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 6dd3a524cd35..9170b5c09823 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -3654,12 +3654,33 @@ static int send_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
 	return error;
 }
 
-/* FIXME: if this lkb is the only lock we hold on the rsb, then set
-   MASTER_UNCERTAIN to force the next request on the rsb to confirm
-   that the master is still correct. */
-
 static int send_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
 {
+	struct dlm_lkb *tmp;
+	int count = 0;
+
+	list_for_each_entry(tmp, &r->res_grantqueue, lkb_statequeue) {
+		if (is_process_copy(tmp))
+			count++;
+	}
+	list_for_each_entry(tmp, &r->res_convertqueue, lkb_statequeue) {
+		if (is_process_copy(tmp))
+			count++;
+	}
+	list_for_each_entry(tmp, &r->res_waitqueue, lkb_statequeue) {
+		if (is_process_copy(tmp))
+			count++;
+	}
+
+/*
+ * When releasing the last lock on the rsb, we mark the master as uncertain.
+ * This ensures that the next lock request will verify the master node,
+ * maintaining consistency across the cluster.
+ */
+
+	if (count == 1)
+		rsb_set_flag(r, RSB_MASTER_UNCERTAIN);
+
 	return send_common(r, lkb, DLM_MSG_UNLOCK);
 }
 
@@ -6125,79 +6146,52 @@ static int unlock_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
 	return error;
 }
 
-/* We have to release clear_proc_locks mutex before calling unlock_proc_lock()
-   (which does lock_rsb) due to deadlock with receiving a message that does
-   lock_rsb followed by dlm_user_add_cb() */
-
-static struct dlm_lkb *del_proc_lock(struct dlm_ls *ls,
-				     struct dlm_user_proc *proc)
-{
-	struct dlm_lkb *lkb = NULL;
-
-	spin_lock_bh(&ls->ls_clear_proc_locks);
-	if (list_empty(&proc->locks))
-		goto out;
-
-	lkb = list_entry(proc->locks.next, struct dlm_lkb, lkb_ownqueue);
-	list_del_init(&lkb->lkb_ownqueue);
-
-	if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
-		set_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags);
-	else
-		set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
- out:
-	spin_unlock_bh(&ls->ls_clear_proc_locks);
-	return lkb;
-}
-
-/* The ls_clear_proc_locks mutex protects against dlm_user_add_cb() which
-   1) references lkb->ua which we free here and 2) adds lkbs to proc->asts,
-   which we clear here. */
-
-/* proc CLOSING flag is set so no more device_reads should look at proc->asts
-   list, and no more device_writes should add lkb's to proc->locks list; so we
-   shouldn't need to take asts_spin or locks_spin here.  this assumes that
-   device reads/writes/closes are serialized -- FIXME: we may need to serialize
-   them ourself. */
-
-void dlm_clear_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
+static void clean_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
 {
-	struct dlm_callback *cb, *cb_safe;
-	struct dlm_lkb *lkb, *safe;
+	struct dlm_lkb *lkb;
 
 	dlm_lock_recovery(ls);
 
 	while (1) {
-		lkb = del_proc_lock(ls, proc);
+		lkb = NULL;
+		spin_lock_bh(&proc->locks_spin);
+		if (!list_empty(&proc->locks)) {
+			lkb = list_entry(proc->locks.next, struct dlm_lkb,
+					 lkb_ownqueue);
+			list_del_init(&lkb->lkb_ownqueue);
+		}
+		spin_unlock_bh(&proc->locks_spin);
+
 		if (!lkb)
 			break;
-		if (lkb->lkb_exflags & DLM_LKF_PERSISTENT)
+
+		if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) {
+			set_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags);
 			orphan_proc_lock(ls, lkb);
-		else
+		} else {
+			set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
 			unlock_proc_lock(ls, lkb);
-
-		/* this removes the reference for the proc->locks list
-		   added by dlm_user_request, it may result in the lkb
-		   being freed */
+		}
 
 		dlm_put_lkb(lkb);
 	}
 
-	spin_lock_bh(&ls->ls_clear_proc_locks);
-
+	spin_lock_bh(&proc->locks_spin);
 	/* in-progress unlocks */
 	list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
 		list_del_init(&lkb->lkb_ownqueue);
 		set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
 		dlm_put_lkb(lkb);
 	}
+	spin_unlock_bh(&proc->locks_spin);
 
+	spin_lock_bh(&proc->asts_spin);
 	list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
 		list_del(&cb->list);
 		dlm_free_cb(cb);
 	}
+	spin_unlock_bh(&proc->asts_spin);
 
-	spin_unlock_bh(&ls->ls_clear_proc_locks);
 	dlm_unlock_recovery(ls);
 }
 
@@ -6351,4 +6345,3 @@ int dlm_debug_add_lkb_to_waiters(struct dlm_ls *ls, uint32_t lkb_id,
 	dlm_put_lkb(lkb);
 	return 0;
 }
-
-- 
2.48.1
Re: [PATCH] * dlm: improve lock management and concurrency control
Posted by kernel test robot 4 months, 4 weeks ago
Hi Alessio,

kernel test robot noticed the following build warnings:

[auto build test WARNING on teigland-dlm/next]
[also build test WARNING on linus/master v6.17-rc5 next-20250911]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alessio-Attilio/dlm-improve-lock-management-and-concurrency-control/20250911-012449
base:   https://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git next
patch link:    https://lore.kernel.org/r/20250910171706.173976-1-alessio.attilio.dev%40gmail.com
patch subject: [PATCH] * dlm: improve lock management and concurrency control
config: sh-allyesconfig (https://download.01.org/0day-ci/archive/20250911/202509112200.zlSc9HkB-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250911/202509112200.zlSc9HkB-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509112200.zlSc9HkB-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from include/linux/smp.h:12,
                    from include/linux/tracepoint.h:15,
                    from include/trace/events/dlm.h:11,
                    from fs/dlm/lock.c:56:
   fs/dlm/lock.c: In function 'clean_proc_locks':
   fs/dlm/lock.c:6181:39: error: 'safe' undeclared (first use in this function)
    6181 |         list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
         |                                       ^~~~
   include/linux/list.h:858:17: note: in definition of macro 'list_for_each_entry_safe'
     858 |                 n = list_next_entry(pos, member);                       \
         |                 ^
   fs/dlm/lock.c:6181:39: note: each undeclared identifier is reported only once for each function it appears in
    6181 |         list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
         |                                       ^~~~
   include/linux/list.h:858:17: note: in definition of macro 'list_for_each_entry_safe'
     858 |                 n = list_next_entry(pos, member);                       \
         |                 ^
   In file included from include/linux/container_of.h:5,
                    from include/linux/list.h:5:
   include/linux/compiler_types.h:507:27: error: expression in static assertion is not an integer
     507 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:601:9: note: in expansion of macro 'container_of'
     601 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:645:9: note: in expansion of macro 'list_entry'
     645 |         list_entry((pos)->member.next, typeof(*(pos)), member)
         |         ^~~~~~~~~~
   include/linux/list.h:860:27: note: in expansion of macro 'list_next_entry'
     860 |              pos = n, n = list_next_entry(n, member))
         |                           ^~~~~~~~~~~~~~~
   fs/dlm/lock.c:6181:9: note: in expansion of macro 'list_for_each_entry_safe'
    6181 |         list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/list.h:860:21: warning: left-hand operand of comma expression has no effect [-Wunused-value]
     860 |              pos = n, n = list_next_entry(n, member))
         |                     ^
   fs/dlm/lock.c:6181:9: note: in expansion of macro 'list_for_each_entry_safe'
    6181 |         list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   fs/dlm/lock.c:6189:34: error: 'cb' undeclared (first use in this function); did you mean 'mb'?
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |                                  ^~
   include/linux/list.h:857:14: note: in definition of macro 'list_for_each_entry_safe'
     857 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |              ^~~
   include/linux/compiler_types.h:507:27: error: expression in static assertion is not an integer
     507 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:601:9: note: in expansion of macro 'container_of'
     601 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:612:9: note: in expansion of macro 'list_entry'
     612 |         list_entry((ptr)->next, type, member)
         |         ^~~~~~~~~~
   include/linux/list.h:857:20: note: in expansion of macro 'list_first_entry'
     857 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                    ^~~~~~~~~~~~~~~~
   fs/dlm/lock.c:6189:9: note: in expansion of macro 'list_for_each_entry_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   fs/dlm/lock.c:6189:38: error: 'cb_safe' undeclared (first use in this function)
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |                                      ^~~~~~~
   include/linux/list.h:858:17: note: in definition of macro 'list_for_each_entry_safe'
     858 |                 n = list_next_entry(pos, member);                       \
         |                 ^
   include/linux/compiler_types.h:507:27: error: expression in static assertion is not an integer
     507 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:601:9: note: in expansion of macro 'container_of'
     601 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:645:9: note: in expansion of macro 'list_entry'
     645 |         list_entry((pos)->member.next, typeof(*(pos)), member)
         |         ^~~~~~~~~~
   include/linux/list.h:858:21: note: in expansion of macro 'list_next_entry'
     858 |                 n = list_next_entry(pos, member);                       \
         |                     ^~~~~~~~~~~~~~~
   fs/dlm/lock.c:6189:9: note: in expansion of macro 'list_for_each_entry_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/list.h:857:64: warning: left-hand operand of comma expression has no effect [-Wunused-value]
     857 |         for (pos = list_first_entry(head, typeof(*pos), member),        \
         |                                                                ^
   fs/dlm/lock.c:6189:9: note: in expansion of macro 'list_for_each_entry_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/compiler_types.h:507:27: error: expression in static assertion is not an integer
     507 | #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
         |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/build_bug.h:78:56: note: in definition of macro '__static_assert'
      78 | #define __static_assert(expr, msg, ...) _Static_assert(expr, msg)
         |                                                        ^~~~
   include/linux/container_of.h:21:9: note: in expansion of macro 'static_assert'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |         ^~~~~~~~~~~~~
   include/linux/container_of.h:21:23: note: in expansion of macro '__same_type'
      21 |         static_assert(__same_type(*(ptr), ((type *)0)->member) ||       \
         |                       ^~~~~~~~~~~
   include/linux/list.h:601:9: note: in expansion of macro 'container_of'
     601 |         container_of(ptr, type, member)
         |         ^~~~~~~~~~~~
   include/linux/list.h:645:9: note: in expansion of macro 'list_entry'
     645 |         list_entry((pos)->member.next, typeof(*(pos)), member)
         |         ^~~~~~~~~~
   include/linux/list.h:860:27: note: in expansion of macro 'list_next_entry'
     860 |              pos = n, n = list_next_entry(n, member))
         |                           ^~~~~~~~~~~~~~~
   fs/dlm/lock.c:6189:9: note: in expansion of macro 'list_for_each_entry_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/list.h:860:21: warning: left-hand operand of comma expression has no effect [-Wunused-value]
     860 |              pos = n, n = list_next_entry(n, member))
         |                     ^
   fs/dlm/lock.c:6189:9: note: in expansion of macro 'list_for_each_entry_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |         ^~~~~~~~~~~~~~~~~~~~~~~~
   fs/dlm/lock.c: At top level:
>> fs/dlm/lock.c:6149:13: warning: 'clean_proc_locks' defined but not used [-Wunused-function]
    6149 | static void clean_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
         |             ^~~~~~~~~~~~~~~~


vim +/clean_proc_locks +6149 fs/dlm/lock.c

  6148	
> 6149	static void clean_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
  6150	{
  6151		struct dlm_lkb *lkb;
  6152	
  6153		dlm_lock_recovery(ls);
  6154	
  6155		while (1) {
  6156			lkb = NULL;
  6157			spin_lock_bh(&proc->locks_spin);
  6158			if (!list_empty(&proc->locks)) {
  6159				lkb = list_entry(proc->locks.next, struct dlm_lkb,
  6160						 lkb_ownqueue);
  6161				list_del_init(&lkb->lkb_ownqueue);
  6162			}
  6163			spin_unlock_bh(&proc->locks_spin);
  6164	
  6165			if (!lkb)
  6166				break;
  6167	
  6168			if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) {
  6169				set_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags);
  6170				orphan_proc_lock(ls, lkb);
  6171			} else {
  6172				set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
  6173				unlock_proc_lock(ls, lkb);
  6174			}
  6175	
  6176			dlm_put_lkb(lkb);
  6177		}
  6178	
  6179		spin_lock_bh(&proc->locks_spin);
  6180		/* in-progress unlocks */
  6181		list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
  6182			list_del_init(&lkb->lkb_ownqueue);
  6183			set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
  6184			dlm_put_lkb(lkb);
  6185		}
  6186		spin_unlock_bh(&proc->locks_spin);
  6187	
  6188		spin_lock_bh(&proc->asts_spin);
  6189		list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
  6190			list_del(&cb->list);
  6191			dlm_free_cb(cb);
  6192		}
  6193		spin_unlock_bh(&proc->asts_spin);
  6194	
  6195		dlm_unlock_recovery(ls);
  6196	}
  6197	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] * dlm: improve lock management and concurrency control
Posted by Alexander Aring 4 months, 4 weeks ago
Hi,

On Wed, Sep 10, 2025 at 1:23 PM Alessio Attilio
<alessio.attilio.dev@gmail.com> wrote:
>
> From: Alessio Attilio <alessio.attilio@engineer.com>
>
> This patch introduces several improvements to lock handling in the DLM
> subsystem, focusing on thread safety, correctness, and code clarity.
>
> - Added explicit locking (spin_lock_bh/spin_unlock_bh) around accesses
>   to proc->locks and proc->asts in dlm_clear_proc_locks, ensuring safe
>   concurrent operations during lock cleanup.
> - Replaced del_proc_lock with direct, lock-protected list operations
>   for improved clarity and correctness.
> - Updated send_unlock to set RSB_MASTER_UNCERTAIN only when releasing
>   the last lock on an rsb, ensuring proper master confirmation.
> - Improved handling of persistent and non-persistent locks by setting
>   appropriate flags (DLM_DFL_ORPHAN_BIT or DLM_IFL_DEAD_BIT) before
>   orphaning or unlocking.
> - Removed outdated comments related to mutex protection and serialization
>   assumptions, reflecting the updated concurrency model.
>
> Signed-off-by: Alessio Attilio <alessio.attilio.dev@gmail.com>

The patch doesn't compile for me as well. Please also make sure to run
"scripts/checkpatch.pl" on your patch before sending it.

> ---
>  fs/dlm/lock.c | 99 ++++++++++++++++++++++++---------------------------
>  1 file changed, 46 insertions(+), 53 deletions(-)
>
> diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
> index 6dd3a524cd35..9170b5c09823 100644
> --- a/fs/dlm/lock.c
> +++ b/fs/dlm/lock.c
> @@ -3654,12 +3654,33 @@ static int send_convert(struct dlm_rsb *r, struct dlm_lkb *lkb)
>         return error;
>  }
>
> -/* FIXME: if this lkb is the only lock we hold on the rsb, then set
> -   MASTER_UNCERTAIN to force the next request on the rsb to confirm
> -   that the master is still correct. */
> -
>  static int send_unlock(struct dlm_rsb *r, struct dlm_lkb *lkb)
>  {
> +       struct dlm_lkb *tmp;
> +       int count = 0;
> +
> +       list_for_each_entry(tmp, &r->res_grantqueue, lkb_statequeue) {
> +               if (is_process_copy(tmp))
> +                       count++;
> +       }
> +       list_for_each_entry(tmp, &r->res_convertqueue, lkb_statequeue) {
> +               if (is_process_copy(tmp))
> +                       count++;
> +       }
> +       list_for_each_entry(tmp, &r->res_waitqueue, lkb_statequeue) {
> +               if (is_process_copy(tmp))
> +                       count++;
> +       }
> +
> +/*
> + * When releasing the last lock on the rsb, we mark the master as uncertain.
> + * This ensures that the next lock request will verify the master node,
> + * maintaining consistency across the cluster.
> + */

After unlocking the rsb should be moved to the inactive/toss state, if
it's activated again it should be that there is a new lookup being
done when it's necessary.
This however is not being done at the state here. As you describe the
problem it is about multiple concurrent requests the problem might be
something different.
There should be no cancel/unlock requests at the same time, cancel is
only for requests or converts not for unlock, maybe what's missing
here is to check on an invalid API usage at [0]?

As far as I understood from your problem specification, a
stacktrace/reproducer/coredump would be much more helpful here.

...
> -       spin_lock_bh(&ls->ls_clear_proc_locks);
> -
> +       spin_lock_bh(&proc->locks_spin);
>         /* in-progress unlocks */
>         list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
>                 list_del_init(&lkb->lkb_ownqueue);
>                 set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
>                 dlm_put_lkb(lkb);
>         }
> +       spin_unlock_bh(&proc->locks_spin);
>
> +       spin_lock_bh(&proc->asts_spin);
>         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
>                 list_del(&cb->list);
>                 dlm_free_cb(cb);
>         }
> +       spin_unlock_bh(&proc->asts_spin);
>
> -       spin_unlock_bh(&ls->ls_clear_proc_locks);

This lock has after your patch only one lock/unlock user in user.c
which makes this lock obsolete, however it seems your user.c changes
are not part of your patch and got somehow missed.

- Alex

[0] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/dlm/lock.c?h=v6.17-rc5#n2892
Re: [PATCH] * dlm: improve lock management and concurrency control
Posted by kernel test robot 4 months, 4 weeks ago
Hi Alessio,

kernel test robot noticed the following build errors:

[auto build test ERROR on teigland-dlm/next]
[also build test ERROR on linus/master v6.17-rc5 next-20250911]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Alessio-Attilio/dlm-improve-lock-management-and-concurrency-control/20250911-012449
base:   https://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm.git next
patch link:    https://lore.kernel.org/r/20250910171706.173976-1-alessio.attilio.dev%40gmail.com
patch subject: [PATCH] * dlm: improve lock management and concurrency control
config: hexagon-randconfig-001-20250911 (https://download.01.org/0day-ci/archive/20250911/202509112216.Jvy0G9Jd-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250911/202509112216.Jvy0G9Jd-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202509112216.Jvy0G9Jd-lkp@intel.com/

All errors (new ones prefixed by >>):

>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
    6181 |         list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
         |                                       ^
>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
>> fs/dlm/lock.c:6181:32: error: use of undeclared identifier 'safe'
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |                                  ^
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
>> fs/dlm/lock.c:6189:31: error: use of undeclared identifier 'cb_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |                                      ^
>> fs/dlm/lock.c:6189:27: error: use of undeclared identifier 'cb'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |                                  ^
>> fs/dlm/lock.c:6189:31: error: use of undeclared identifier 'cb_safe'
    6189 |         list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
         |                                      ^
>> fs/dlm/lock.c:6189:31: error: use of undeclared identifier 'cb_safe'
>> fs/dlm/lock.c:6189:31: error: use of undeclared identifier 'cb_safe'
   fatal error: too many errors emitted, stopping now [-ferror-limit=]
   20 errors generated.


vim +/safe +6181 fs/dlm/lock.c

597d0cae0f99f6 David Teigland  2006-07-12  6148  
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6149  static void clean_proc_locks(struct dlm_ls *ls, struct dlm_user_proc *proc)
ef0c2bb05f40f9 David Teigland  2007-03-28  6150  {
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6151  	struct dlm_lkb *lkb;
ef0c2bb05f40f9 David Teigland  2007-03-28  6152  
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6153  	dlm_lock_recovery(ls);
ef0c2bb05f40f9 David Teigland  2007-03-28  6154  
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6155  	while (1) {
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6156  		lkb = NULL;
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6157  		spin_lock_bh(&proc->locks_spin);
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6158  		if (!list_empty(&proc->locks)) {
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6159  			lkb = list_entry(proc->locks.next, struct dlm_lkb,
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6160  					 lkb_ownqueue);
ef0c2bb05f40f9 David Teigland  2007-03-28  6161  			list_del_init(&lkb->lkb_ownqueue);
ef0c2bb05f40f9 David Teigland  2007-03-28  6162  		}
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6163  		spin_unlock_bh(&proc->locks_spin);
ef0c2bb05f40f9 David Teigland  2007-03-28  6164  
ef0c2bb05f40f9 David Teigland  2007-03-28  6165  		if (!lkb)
ef0c2bb05f40f9 David Teigland  2007-03-28  6166  			break;
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6167  
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6168  		if (lkb->lkb_exflags & DLM_LKF_PERSISTENT) {
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6169  			set_bit(DLM_DFL_ORPHAN_BIT, &lkb->lkb_dflags);
597d0cae0f99f6 David Teigland  2006-07-12  6170  			orphan_proc_lock(ls, lkb);
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6171  		} else {
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6172  			set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
597d0cae0f99f6 David Teigland  2006-07-12  6173  			unlock_proc_lock(ls, lkb);
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6174  		}
597d0cae0f99f6 David Teigland  2006-07-12  6175  
597d0cae0f99f6 David Teigland  2006-07-12  6176  		dlm_put_lkb(lkb);
597d0cae0f99f6 David Teigland  2006-07-12  6177  	}
a1bc86e6bddd34 David Teigland  2007-01-15  6178  
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6179  	spin_lock_bh(&proc->locks_spin);
a1bc86e6bddd34 David Teigland  2007-01-15  6180  	/* in-progress unlocks */
a1bc86e6bddd34 David Teigland  2007-01-15 @6181  	list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) {
a1bc86e6bddd34 David Teigland  2007-01-15  6182  		list_del_init(&lkb->lkb_ownqueue);
e1af8728f600f6 Alexander Aring 2023-03-06  6183  		set_bit(DLM_IFL_DEAD_BIT, &lkb->lkb_iflags);
a1bc86e6bddd34 David Teigland  2007-01-15  6184  		dlm_put_lkb(lkb);
a1bc86e6bddd34 David Teigland  2007-01-15  6185  	}
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6186  	spin_unlock_bh(&proc->locks_spin);
a1bc86e6bddd34 David Teigland  2007-01-15  6187  
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6188  	spin_lock_bh(&proc->asts_spin);
986ae3c2a8dfc1 Alexander Aring 2024-03-28 @6189  	list_for_each_entry_safe(cb, cb_safe, &proc->asts, list) {
986ae3c2a8dfc1 Alexander Aring 2024-03-28  6190  		list_del(&cb->list);
2bec1bbd55cf96 Alexander Aring 2024-03-28  6191  		dlm_free_cb(cb);
a1bc86e6bddd34 David Teigland  2007-01-15  6192  	}
cc9f8fbfb34e86 Alessio Attilio 2025-09-10  6193  	spin_unlock_bh(&proc->asts_spin);
a1bc86e6bddd34 David Teigland  2007-01-15  6194  
85e86edf951a8a David Teigland  2007-05-18  6195  	dlm_unlock_recovery(ls);
597d0cae0f99f6 David Teigland  2006-07-12  6196  }
a1bc86e6bddd34 David Teigland  2007-01-15  6197  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki