From 455597a55f402e52e1c577c921bf5fe3aa4d2281 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 2 Apr 2024 15:17:58 -0400 Subject: dlm: switch to GFP_ATOMIC in dlm allocations Replace GFP_NOFS with GFP_ATOMIC. Also stop using idr_preload which uses a non-bh spin_lock. This is further preparation for softirq message processing. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/requestqueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/dlm/requestqueue.c') diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 892d6ca21e74..c05940afd063 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c @@ -37,7 +37,7 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, int length = le16_to_cpu(ms->m_header.h_length) - sizeof(struct dlm_message); - e = kmalloc(sizeof(struct rq_entry) + length, GFP_NOFS); + e = kmalloc(sizeof(struct rq_entry) + length, GFP_ATOMIC); if (!e) { log_print("dlm_add_requestqueue: out of memory len %d", length); return; -- cgit From c288745f1d4a2ead903e81d2f4716e9d40b0ad85 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 2 Apr 2024 15:18:06 -0400 Subject: dlm: avoid blocking receive at the end of recovery The end of the recovery process transitioned to normal message processing by temporarily blocking the receiving context, processing saved messages, then unblocking the receiving context. To avoid blocking the receiving context, the old wait_queue and mutex are replaced by a new rwlock and the new RECV_MSG_BLOCKED flag. Received messages are added to the list of saved messages, protected by the rwlock, until the flag is cleared, which happens when all saved messages have been processed. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/requestqueue.c | 41 ++++++++--------------------------------- 1 file changed, 8 insertions(+), 33 deletions(-) (limited to 'fs/dlm/requestqueue.c') diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index c05940afd063..9b646026df46 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c @@ -48,10 +48,7 @@ void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, memcpy(&e->request, ms, sizeof(*ms)); memcpy(&e->request.m_extra, ms->m_extra, length); - atomic_inc(&ls->ls_requestqueue_cnt); - mutex_lock(&ls->ls_requestqueue_mutex); list_add_tail(&e->list, &ls->ls_requestqueue); - mutex_unlock(&ls->ls_requestqueue_mutex); } /* @@ -71,16 +68,14 @@ int dlm_process_requestqueue(struct dlm_ls *ls) struct dlm_message *ms; int error = 0; - mutex_lock(&ls->ls_requestqueue_mutex); - + write_lock(&ls->ls_requestqueue_lock); for (;;) { if (list_empty(&ls->ls_requestqueue)) { - mutex_unlock(&ls->ls_requestqueue_mutex); + clear_bit(LSFL_RECV_MSG_BLOCKED, &ls->ls_flags); error = 0; break; } - e = list_entry(ls->ls_requestqueue.next, struct rq_entry, list); - mutex_unlock(&ls->ls_requestqueue_mutex); + e = list_first_entry(&ls->ls_requestqueue, struct rq_entry, list); ms = &e->request; @@ -93,41 +88,23 @@ int dlm_process_requestqueue(struct dlm_ls *ls) e->recover_seq); dlm_receive_message_saved(ls, &e->request, e->recover_seq); - - mutex_lock(&ls->ls_requestqueue_mutex); list_del(&e->list); - if (atomic_dec_and_test(&ls->ls_requestqueue_cnt)) - wake_up(&ls->ls_requestqueue_wait); kfree(e); if (dlm_locking_stopped(ls)) { log_debug(ls, "process_requestqueue abort running"); - mutex_unlock(&ls->ls_requestqueue_mutex); error = -EINTR; break; } + write_unlock(&ls->ls_requestqueue_lock); schedule(); + write_lock(&ls->ls_requestqueue_lock); } + write_unlock(&ls->ls_requestqueue_lock); return error; } -/* - * After recovery is done, locking is resumed and dlm_recoverd takes all the - * saved requests and processes them as they would have been by dlm_recv. At - * the same time, dlm_recv will start receiving new requests from remote nodes. - * We want to delay dlm_recv processing new requests until dlm_recoverd has - * finished processing the old saved requests. We don't check for locking - * stopped here because dlm_ls_stop won't stop locking until it's suspended us - * (dlm_recv). - */ - -void dlm_wait_requestqueue(struct dlm_ls *ls) -{ - wait_event(ls->ls_requestqueue_wait, - atomic_read(&ls->ls_requestqueue_cnt) == 0); -} - static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid) { __le32 type = ms->m_type; @@ -158,17 +135,15 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) struct dlm_message *ms; struct rq_entry *e, *safe; - mutex_lock(&ls->ls_requestqueue_mutex); + write_lock(&ls->ls_requestqueue_lock); list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { ms = &e->request; if (purge_request(ls, ms, e->nodeid)) { list_del(&e->list); - if (atomic_dec_and_test(&ls->ls_requestqueue_cnt)) - wake_up(&ls->ls_requestqueue_wait); kfree(e); } } - mutex_unlock(&ls->ls_requestqueue_mutex); + write_unlock(&ls->ls_requestqueue_lock); } -- cgit From 578acf9a87a87531df5b59b3799ccc1256a4bbcc Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 2 Apr 2024 15:18:09 -0400 Subject: dlm: use spin_lock_bh for message processing Use spin_lock_bh for all spinlocks involved in message processing, in preparation for softirq message processing. DLM lock requests from user space involve dlm processing in user context, in addition to the standard kernel context, necessitating bh variants. Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/requestqueue.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'fs/dlm/requestqueue.c') diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 9b646026df46..719a5243a069 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c @@ -68,7 +68,7 @@ int dlm_process_requestqueue(struct dlm_ls *ls) struct dlm_message *ms; int error = 0; - write_lock(&ls->ls_requestqueue_lock); + write_lock_bh(&ls->ls_requestqueue_lock); for (;;) { if (list_empty(&ls->ls_requestqueue)) { clear_bit(LSFL_RECV_MSG_BLOCKED, &ls->ls_flags); @@ -96,11 +96,11 @@ int dlm_process_requestqueue(struct dlm_ls *ls) error = -EINTR; break; } - write_unlock(&ls->ls_requestqueue_lock); + write_unlock_bh(&ls->ls_requestqueue_lock); schedule(); - write_lock(&ls->ls_requestqueue_lock); + write_lock_bh(&ls->ls_requestqueue_lock); } - write_unlock(&ls->ls_requestqueue_lock); + write_unlock_bh(&ls->ls_requestqueue_lock); return error; } @@ -135,7 +135,7 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) struct dlm_message *ms; struct rq_entry *e, *safe; - write_lock(&ls->ls_requestqueue_lock); + write_lock_bh(&ls->ls_requestqueue_lock); list_for_each_entry_safe(e, safe, &ls->ls_requestqueue, list) { ms = &e->request; @@ -144,6 +144,6 @@ void dlm_purge_requestqueue(struct dlm_ls *ls) kfree(e); } } - write_unlock(&ls->ls_requestqueue_lock); + write_unlock_bh(&ls->ls_requestqueue_lock); } -- cgit