From a5ca5ee36da6234e43baed93821e69cd6f3f3314 Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Thu, 29 Apr 2021 14:22:30 -0700 Subject: [PATCH] Put back-to-back invalidated locks back on list A lock that is undergoing invalidation is put on a list of locks in the super block. Invalidation requests put locks on the list. While locks are invalidated they're temporarily put on a private list. To support a request arriving while the lock is being processed we carefully manage the invalidation fields in the lock between the invalidation worker and the incoming request. The worker correctly noticed that a new invalidation request had arrived but it left the lock on its private list instead of putting it back on the invalidation list for further processing. The lock was unreachable, wouldn't get invalidated, and caused everyone trying to use the lock to block indefinitely. When the worker sees another request arrive for an invalidating lock it needs to move the lock from the private list back to the invalidation list. Signed-off-by: Zach Brown --- kmod/src/lock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kmod/src/lock.c b/kmod/src/lock.c index a091ca68..50a33d26 100644 --- a/kmod/src/lock.c +++ b/kmod/src/lock.c @@ -894,6 +894,9 @@ static void lock_invalidate_worker(struct work_struct *work) list_del_init(&lock->inv_head); lock->invalidate_pending = 0; wake_up(&lock->waitq); + } else { + /* another request filled nl/net_id, put it back on the list */ + list_move_tail(&lock->inv_head, &linfo->inv_list); } put_lock(linfo, lock); }