1 From c6ff669bac5c409f4cb74366248f51b73f7d6feb Mon Sep 17 00:00:00 2001
2 From: David Teigland <teigland@redhat.com>
3 Date: Mon, 28 Mar 2011 14:17:26 -0500
4 Subject: [PATCH 1/1] dlm: delayed reply message warning
6 Add an option (disabled by default) to print a warning message
7 when a lock has been waiting a configurable amount of time for
8 a reply message from another node. This is mainly for debugging.
10 Signed-off-by: David Teigland <teigland@redhat.com>
12 fs/dlm/config.c | 9 ++++-
14 fs/dlm/dlm_internal.h | 2 +
15 fs/dlm/lock.c | 100 +++++++++++++++++++++++++++++++++++++++++++++---
17 fs/dlm/lockspace.c | 6 +-
18 6 files changed, 108 insertions(+), 11 deletions(-)
20 diff --git a/fs/dlm/config.c b/fs/dlm/config.c
21 index 0d329ff..9b026ea 100644
24 @@ -100,6 +100,7 @@ struct dlm_cluster {
25 unsigned int cl_log_debug;
26 unsigned int cl_protocol;
27 unsigned int cl_timewarn_cs;
28 + unsigned int cl_waitwarn_us;
32 @@ -114,6 +115,7 @@ enum {
33 CLUSTER_ATTR_LOG_DEBUG,
34 CLUSTER_ATTR_PROTOCOL,
35 CLUSTER_ATTR_TIMEWARN_CS,
36 + CLUSTER_ATTR_WAITWARN_US,
39 struct cluster_attribute {
40 @@ -166,6 +168,7 @@ CLUSTER_ATTR(scan_secs, 1);
41 CLUSTER_ATTR(log_debug, 0);
42 CLUSTER_ATTR(protocol, 0);
43 CLUSTER_ATTR(timewarn_cs, 1);
44 +CLUSTER_ATTR(waitwarn_us, 0);
46 static struct configfs_attribute *cluster_attrs[] = {
47 [CLUSTER_ATTR_TCP_PORT] = &cluster_attr_tcp_port.attr,
48 @@ -179,6 +182,7 @@ static struct configfs_attribute *cluster_attrs[] = {
49 [CLUSTER_ATTR_LOG_DEBUG] = &cluster_attr_log_debug.attr,
50 [CLUSTER_ATTR_PROTOCOL] = &cluster_attr_protocol.attr,
51 [CLUSTER_ATTR_TIMEWARN_CS] = &cluster_attr_timewarn_cs.attr,
52 + [CLUSTER_ATTR_WAITWARN_US] = &cluster_attr_waitwarn_us.attr,
56 @@ -439,6 +443,7 @@ static struct config_group *make_cluster(struct config_group *g,
57 cl->cl_log_debug = dlm_config.ci_log_debug;
58 cl->cl_protocol = dlm_config.ci_protocol;
59 cl->cl_timewarn_cs = dlm_config.ci_timewarn_cs;
60 + cl->cl_waitwarn_us = dlm_config.ci_waitwarn_us;
62 space_list = &sps->ss_group;
63 comm_list = &cms->cs_group;
64 @@ -986,6 +991,7 @@ int dlm_our_addr(struct sockaddr_storage *addr, int num)
65 #define DEFAULT_LOG_DEBUG 0
66 #define DEFAULT_PROTOCOL 0
67 #define DEFAULT_TIMEWARN_CS 500 /* 5 sec = 500 centiseconds */
68 +#define DEFAULT_WAITWARN_US 0
70 struct dlm_config_info dlm_config = {
71 .ci_tcp_port = DEFAULT_TCP_PORT,
72 @@ -998,6 +1004,7 @@ struct dlm_config_info dlm_config = {
73 .ci_scan_secs = DEFAULT_SCAN_SECS,
74 .ci_log_debug = DEFAULT_LOG_DEBUG,
75 .ci_protocol = DEFAULT_PROTOCOL,
76 - .ci_timewarn_cs = DEFAULT_TIMEWARN_CS
77 + .ci_timewarn_cs = DEFAULT_TIMEWARN_CS,
78 + .ci_waitwarn_us = DEFAULT_WAITWARN_US
81 diff --git a/fs/dlm/config.h b/fs/dlm/config.h
82 index 4f1d6fc..dd0ce24 100644
85 @@ -28,6 +28,7 @@ struct dlm_config_info {
92 extern struct dlm_config_info dlm_config;
93 diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
94 index b942049..6a92478 100644
95 --- a/fs/dlm/dlm_internal.h
96 +++ b/fs/dlm/dlm_internal.h
97 @@ -245,6 +245,7 @@ struct dlm_lkb {
99 int8_t lkb_wait_type; /* type of reply waiting for */
100 int8_t lkb_wait_count;
101 + int lkb_wait_nodeid; /* for debugging */
103 struct list_head lkb_idtbl_list; /* lockspace lkbtbl */
104 struct list_head lkb_statequeue; /* rsb g/c/w list */
105 @@ -254,6 +255,7 @@ struct dlm_lkb {
106 struct list_head lkb_ownqueue; /* list of locks for a process */
107 struct list_head lkb_time_list;
108 ktime_t lkb_timestamp;
109 + ktime_t lkb_wait_time;
110 unsigned long lkb_timeout_cs;
112 struct dlm_callback lkb_callbacks[DLM_CALLBACKS_SIZE];
113 diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
114 index 04b8c44..e3c8641 100644
117 @@ -799,10 +799,84 @@ static int msg_reply_type(int mstype)
121 +static int nodeid_warned(int nodeid, int num_nodes, int *warned)
125 + for (i = 0; i < num_nodes; i++) {
127 + warned[i] = nodeid;
130 + if (warned[i] == nodeid)
136 +void dlm_scan_waiters(struct dlm_ls *ls)
138 + struct dlm_lkb *lkb;
139 + ktime_t zero = ktime_set(0, 0);
141 + s64 debug_maxus = 0;
142 + u32 debug_scanned = 0;
143 + u32 debug_expired = 0;
145 + int *warned = NULL;
147 + if (!dlm_config.ci_waitwarn_us)
150 + mutex_lock(&ls->ls_waiters_mutex);
152 + list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
153 + if (ktime_equal(lkb->lkb_wait_time, zero))
158 + us = ktime_to_us(ktime_sub(ktime_get(), lkb->lkb_wait_time));
160 + if (us < dlm_config.ci_waitwarn_us)
163 + lkb->lkb_wait_time = zero;
166 + if (us > debug_maxus)
170 + num_nodes = ls->ls_num_nodes;
171 + warned = kmalloc(GFP_KERNEL, num_nodes * sizeof(int));
173 + memset(warned, 0, num_nodes * sizeof(int));
177 + if (nodeid_warned(lkb->lkb_wait_nodeid, num_nodes, warned))
180 + log_error(ls, "waitwarn %x %lld %d us check connection to "
181 + "node %d", lkb->lkb_id, (long long)us,
182 + dlm_config.ci_waitwarn_us, lkb->lkb_wait_nodeid);
184 + mutex_unlock(&ls->ls_waiters_mutex);
190 + log_debug(ls, "scan_waiters %u warn %u over %d us max %lld us",
191 + debug_scanned, debug_expired,
192 + dlm_config.ci_waitwarn_us, (long long)debug_maxus);
195 /* add/remove lkb from global waiters list of lkb's waiting for
196 a reply from a remote node */
198 -static int add_to_waiters(struct dlm_lkb *lkb, int mstype)
199 +static int add_to_waiters(struct dlm_lkb *lkb, int mstype, int to_nodeid)
201 struct dlm_ls *ls = lkb->lkb_resource->res_ls;
203 @@ -842,6 +916,8 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype)
205 lkb->lkb_wait_count++;
206 lkb->lkb_wait_type = mstype;
207 + lkb->lkb_wait_time = ktime_get();
208 + lkb->lkb_wait_nodeid = to_nodeid; /* for debugging */
210 list_add(&lkb->lkb_wait_reply, &ls->ls_waiters);
212 @@ -1157,6 +1233,16 @@ void dlm_adjust_timeouts(struct dlm_ls *ls)
213 list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list)
214 lkb->lkb_timestamp = ktime_add_us(lkb->lkb_timestamp, adj_us);
215 mutex_unlock(&ls->ls_timeout_mutex);
217 + if (!dlm_config.ci_waitwarn_us)
220 + mutex_lock(&ls->ls_waiters_mutex);
221 + list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
222 + if (ktime_to_us(lkb->lkb_wait_time))
223 + lkb->lkb_wait_time = ktime_get();
225 + mutex_unlock(&ls->ls_waiters_mutex);
228 /* lkb is master or local copy */
229 @@ -2844,12 +2930,12 @@ static int send_common(struct dlm_rsb *r, struct dlm_lkb *lkb, int mstype)
230 struct dlm_mhandle *mh;
231 int to_nodeid, error;
233 - error = add_to_waiters(lkb, mstype);
234 + to_nodeid = r->res_nodeid;
236 + error = add_to_waiters(lkb, mstype, to_nodeid);
240 - to_nodeid = r->res_nodeid;
242 error = create_message(r, lkb, to_nodeid, mstype, &ms, &mh);
245 @@ -2951,12 +3037,12 @@ static int send_lookup(struct dlm_rsb *r, struct dlm_lkb *lkb)
246 struct dlm_mhandle *mh;
247 int to_nodeid, error;
249 - error = add_to_waiters(lkb, DLM_MSG_LOOKUP);
250 + to_nodeid = dlm_dir_nodeid(r);
252 + error = add_to_waiters(lkb, DLM_MSG_LOOKUP, to_nodeid);
256 - to_nodeid = dlm_dir_nodeid(r);
258 error = create_message(r, NULL, to_nodeid, DLM_MSG_LOOKUP, &ms, &mh);
261 diff --git a/fs/dlm/lock.h b/fs/dlm/lock.h
262 index 88e93c8..265017a 100644
265 @@ -24,6 +24,7 @@ int dlm_put_lkb(struct dlm_lkb *lkb);
266 void dlm_scan_rsbs(struct dlm_ls *ls);
267 int dlm_lock_recovery_try(struct dlm_ls *ls);
268 void dlm_unlock_recovery(struct dlm_ls *ls);
269 +void dlm_scan_waiters(struct dlm_ls *ls);
270 void dlm_scan_timeout(struct dlm_ls *ls);
271 void dlm_adjust_timeouts(struct dlm_ls *ls);
273 diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
274 index f994a7d..14cbf40 100644
275 --- a/fs/dlm/lockspace.c
276 +++ b/fs/dlm/lockspace.c
277 @@ -243,7 +243,6 @@ static struct dlm_ls *find_ls_to_scan(void)
278 static int dlm_scand(void *data)
281 - int timeout_jiffies = dlm_config.ci_scan_secs * HZ;
283 while (!kthread_should_stop()) {
284 ls = find_ls_to_scan();
285 @@ -252,13 +251,14 @@ static int dlm_scand(void *data)
286 ls->ls_scan_time = jiffies;
288 dlm_scan_timeout(ls);
289 + dlm_scan_waiters(ls);
290 dlm_unlock_recovery(ls);
292 ls->ls_scan_time += HZ;
295 - schedule_timeout_interruptible(timeout_jiffies);
298 + schedule_timeout_interruptible(dlm_config.ci_scan_secs * HZ);