1818#include "user.h"
1919#include "ast.h"
2020
21- static void dlm_callback_work (struct work_struct * work )
21+ static void dlm_run_callback (uint32_t ls_id , uint32_t lkb_id , int8_t mode ,
22+ uint32_t flags , uint8_t sb_flags , int sb_status ,
23+ struct dlm_lksb * lksb ,
24+ void (* astfn )(void * astparam ),
25+ void (* bastfn )(void * astparam , int mode ),
26+ void * astparam , const char * res_name ,
27+ size_t res_length )
2228{
23- struct dlm_callback * cb = container_of (work , struct dlm_callback , work );
24-
25- if (cb -> flags & DLM_CB_BAST ) {
26- trace_dlm_bast (cb -> ls_id , cb -> lkb_id , cb -> mode , cb -> res_name ,
27- cb -> res_length );
28- cb -> bastfn (cb -> astparam , cb -> mode );
29- } else if (cb -> flags & DLM_CB_CAST ) {
30- trace_dlm_ast (cb -> ls_id , cb -> lkb_id , cb -> sb_status ,
31- cb -> sb_flags , cb -> res_name , cb -> res_length );
32- cb -> lkb_lksb -> sb_status = cb -> sb_status ;
33- cb -> lkb_lksb -> sb_flags = cb -> sb_flags ;
34- cb -> astfn (cb -> astparam );
29+ if (flags & DLM_CB_BAST ) {
30+ trace_dlm_bast (ls_id , lkb_id , mode , res_name , res_length );
31+ bastfn (astparam , mode );
32+ } else if (flags & DLM_CB_CAST ) {
33+ trace_dlm_ast (ls_id , lkb_id , sb_status , sb_flags , res_name ,
34+ res_length );
35+ lksb -> sb_status = sb_status ;
36+ lksb -> sb_flags = sb_flags ;
37+ astfn (astparam );
3538 }
39+ }
3640
41+ static void dlm_do_callback (struct dlm_callback * cb )
42+ {
43+ dlm_run_callback (cb -> ls_id , cb -> lkb_id , cb -> mode , cb -> flags ,
44+ cb -> sb_flags , cb -> sb_status , cb -> lkb_lksb ,
45+ cb -> astfn , cb -> bastfn , cb -> astparam ,
46+ cb -> res_name , cb -> res_length );
3747 dlm_free_cb (cb );
3848}
3949
40- int dlm_queue_lkb_callback (struct dlm_lkb * lkb , uint32_t flags , int mode ,
41- int status , uint32_t sbflags ,
42- struct dlm_callback * * cb )
50+ static void dlm_callback_work (struct work_struct * work )
51+ {
52+ struct dlm_callback * cb = container_of (work , struct dlm_callback , work );
53+
54+ dlm_do_callback (cb );
55+ }
56+
57+ bool dlm_may_skip_callback (struct dlm_lkb * lkb , uint32_t flags , int mode ,
58+ int status , uint32_t sbflags , int * copy_lvb )
4359{
4460 struct dlm_rsb * rsb = lkb -> lkb_resource ;
45- int rv = DLM_ENQUEUE_CALLBACK_SUCCESS ;
4661 struct dlm_ls * ls = rsb -> res_ls ;
47- int copy_lvb = 0 ;
4862 int prev_mode ;
4963
64+ if (copy_lvb )
65+ * copy_lvb = 0 ;
66+
5067 if (flags & DLM_CB_BAST ) {
5168 /* if cb is a bast, it should be skipped if the blocking mode is
5269 * compatible with the last granted mode
@@ -56,7 +73,7 @@ int dlm_queue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
5673 log_debug (ls , "skip %x bast mode %d for cast mode %d" ,
5774 lkb -> lkb_id , mode ,
5875 lkb -> lkb_last_cast_cb_mode );
59- goto out ;
76+ return true ;
6077 }
6178 }
6279
@@ -74,7 +91,7 @@ int dlm_queue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
7491 (prev_mode > mode && prev_mode > DLM_LOCK_PR )) {
7592 log_debug (ls , "skip %x add bast mode %d for bast mode %d" ,
7693 lkb -> lkb_id , mode , prev_mode );
77- goto out ;
94+ return true ;
7895 }
7996 }
8097
@@ -85,8 +102,10 @@ int dlm_queue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
85102 prev_mode = lkb -> lkb_last_cast_cb_mode ;
86103
87104 if (!status && lkb -> lkb_lksb -> sb_lvbptr &&
88- dlm_lvb_operations [prev_mode + 1 ][mode + 1 ])
89- copy_lvb = 1 ;
105+ dlm_lvb_operations [prev_mode + 1 ][mode + 1 ]) {
106+ if (copy_lvb )
107+ * copy_lvb = 1 ;
108+ }
90109 }
91110
92111 lkb -> lkb_last_cast_cb_mode = mode ;
@@ -96,11 +115,19 @@ int dlm_queue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
96115 lkb -> lkb_last_cb_mode = mode ;
97116 lkb -> lkb_last_cb_flags = flags ;
98117
118+ return false;
119+ }
120+
121+ int dlm_get_cb (struct dlm_lkb * lkb , uint32_t flags , int mode ,
122+ int status , uint32_t sbflags ,
123+ struct dlm_callback * * cb )
124+ {
125+ struct dlm_rsb * rsb = lkb -> lkb_resource ;
126+ struct dlm_ls * ls = rsb -> res_ls ;
127+
99128 * cb = dlm_allocate_cb ();
100- if (!* cb ) {
101- rv = DLM_ENQUEUE_CALLBACK_FAILURE ;
102- goto out ;
103- }
129+ if (WARN_ON_ONCE (!* cb ))
130+ return - ENOMEM ;
104131
105132 /* for tracing */
106133 (* cb )-> lkb_id = lkb -> lkb_id ;
@@ -112,19 +139,34 @@ int dlm_queue_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode,
112139 (* cb )-> mode = mode ;
113140 (* cb )-> sb_status = status ;
114141 (* cb )-> sb_flags = (sbflags & 0x000000FF );
115- (* cb )-> copy_lvb = copy_lvb ;
116142 (* cb )-> lkb_lksb = lkb -> lkb_lksb ;
117143
118- rv = DLM_ENQUEUE_CALLBACK_NEED_SCHED ;
144+ return 0 ;
145+ }
146+
147+ static int dlm_get_queue_cb (struct dlm_lkb * lkb , uint32_t flags , int mode ,
148+ int status , uint32_t sbflags ,
149+ struct dlm_callback * * cb )
150+ {
151+ int rv ;
152+
153+ rv = dlm_get_cb (lkb , flags , mode , status , sbflags , cb );
154+ if (rv )
155+ return rv ;
119156
120- out :
121- return rv ;
157+ (* cb )-> astfn = lkb -> lkb_astfn ;
158+ (* cb )-> bastfn = lkb -> lkb_bastfn ;
159+ (* cb )-> astparam = lkb -> lkb_astparam ;
160+ INIT_WORK (& (* cb )-> work , dlm_callback_work );
161+
162+ return 0 ;
122163}
123164
124165void dlm_add_cb (struct dlm_lkb * lkb , uint32_t flags , int mode , int status ,
125- uint32_t sbflags )
166+ uint32_t sbflags )
126167{
127- struct dlm_ls * ls = lkb -> lkb_resource -> res_ls ;
168+ struct dlm_rsb * rsb = lkb -> lkb_resource ;
169+ struct dlm_ls * ls = rsb -> res_ls ;
128170 struct dlm_callback * cb ;
129171 int rv ;
130172
@@ -133,34 +175,36 @@ void dlm_add_cb(struct dlm_lkb *lkb, uint32_t flags, int mode, int status,
133175 return ;
134176 }
135177
136- rv = dlm_queue_lkb_callback (lkb , flags , mode , status , sbflags ,
137- & cb );
138- switch (rv ) {
139- case DLM_ENQUEUE_CALLBACK_NEED_SCHED :
140- cb -> astfn = lkb -> lkb_astfn ;
141- cb -> bastfn = lkb -> lkb_bastfn ;
142- cb -> astparam = lkb -> lkb_astparam ;
143- INIT_WORK (& cb -> work , dlm_callback_work );
144-
145- spin_lock_bh (& ls -> ls_cb_lock );
146- if (test_bit (LSFL_CB_DELAY , & ls -> ls_flags ))
178+ if (dlm_may_skip_callback (lkb , flags , mode , status , sbflags , NULL ))
179+ return ;
180+
181+ spin_lock_bh (& ls -> ls_cb_lock );
182+ if (test_bit (LSFL_CB_DELAY , & ls -> ls_flags )) {
183+ rv = dlm_get_queue_cb (lkb , flags , mode , status , sbflags , & cb );
184+ if (!rv )
147185 list_add (& cb -> list , & ls -> ls_cb_delay );
148- else
149- queue_work (ls -> ls_callback_wq , & cb -> work );
150- spin_unlock_bh (& ls -> ls_cb_lock );
151- break ;
152- case DLM_ENQUEUE_CALLBACK_SUCCESS :
153- break ;
154- case DLM_ENQUEUE_CALLBACK_FAILURE :
155- fallthrough ;
156- default :
157- WARN_ON_ONCE (1 );
158- break ;
186+ } else {
187+ if (test_bit (LSFL_SOFTIRQ , & ls -> ls_flags )) {
188+ dlm_run_callback (ls -> ls_global_id , lkb -> lkb_id , mode , flags ,
189+ sbflags , status , lkb -> lkb_lksb ,
190+ lkb -> lkb_astfn , lkb -> lkb_bastfn ,
191+ lkb -> lkb_astparam , rsb -> res_name ,
192+ rsb -> res_length );
193+ } else {
194+ rv = dlm_get_queue_cb (lkb , flags , mode , status , sbflags , & cb );
195+ if (!rv )
196+ queue_work (ls -> ls_callback_wq , & cb -> work );
197+ }
159198 }
199+ spin_unlock_bh (& ls -> ls_cb_lock );
160200}
161201
162202int dlm_callback_start (struct dlm_ls * ls )
163203{
204+ if (!test_bit (LSFL_FS , & ls -> ls_flags ) ||
205+ test_bit (LSFL_SOFTIRQ , & ls -> ls_flags ))
206+ return 0 ;
207+
164208 ls -> ls_callback_wq = alloc_ordered_workqueue ("dlm_callback" ,
165209 WQ_HIGHPRI | WQ_MEM_RECLAIM );
166210 if (!ls -> ls_callback_wq ) {
@@ -178,13 +222,15 @@ void dlm_callback_stop(struct dlm_ls *ls)
178222
179223void dlm_callback_suspend (struct dlm_ls * ls )
180224{
181- if (ls -> ls_callback_wq ) {
182- spin_lock_bh (& ls -> ls_cb_lock );
183- set_bit (LSFL_CB_DELAY , & ls -> ls_flags );
184- spin_unlock_bh (& ls -> ls_cb_lock );
225+ if (!test_bit (LSFL_FS , & ls -> ls_flags ))
226+ return ;
227+
228+ spin_lock_bh (& ls -> ls_cb_lock );
229+ set_bit (LSFL_CB_DELAY , & ls -> ls_flags );
230+ spin_unlock_bh (& ls -> ls_cb_lock );
185231
232+ if (ls -> ls_callback_wq )
186233 flush_workqueue (ls -> ls_callback_wq );
187- }
188234}
189235
190236#define MAX_CB_QUEUE 25
@@ -195,14 +241,18 @@ void dlm_callback_resume(struct dlm_ls *ls)
195241 int count = 0 , sum = 0 ;
196242 bool empty ;
197243
198- if (!ls -> ls_callback_wq )
244+ if (!test_bit ( LSFL_FS , & ls -> ls_flags ) )
199245 return ;
200246
201247more :
202248 spin_lock_bh (& ls -> ls_cb_lock );
203249 list_for_each_entry_safe (cb , safe , & ls -> ls_cb_delay , list ) {
204250 list_del (& cb -> list );
205- queue_work (ls -> ls_callback_wq , & cb -> work );
251+ if (test_bit (LSFL_SOFTIRQ , & ls -> ls_flags ))
252+ dlm_do_callback (cb );
253+ else
254+ queue_work (ls -> ls_callback_wq , & cb -> work );
255+
206256 count ++ ;
207257 if (count == MAX_CB_QUEUE )
208258 break ;
0 commit comments