hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/ocfs2/dlmglue.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* -*- mode: c; c-basic-offset: 8; -*-
23 * vim: noexpandtab sw=8 ts=8 sts=0:
34 *
....@@ -6,21 +7,6 @@
67 * Code which implements an OCFS2 specific interface to our DLM.
78 *
89 * Copyright (C) 2003, 2004 Oracle. All rights reserved.
9
- *
10
- * This program is free software; you can redistribute it and/or
11
- * modify it under the terms of the GNU General Public
12
- * License as published by the Free Software Foundation; either
13
- * version 2 of the License, or (at your option) any later version.
14
- *
15
- * This program is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
- * General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public
21
- * License along with this program; if not, write to the
22
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23
- * Boston, MA 021110-1307, USA.
2410 */
2511
2612 #include <linux/types.h>
....@@ -440,6 +426,7 @@
440426 static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
441427 {
442428 res->l_lock_refresh = 0;
429
+ res->l_lock_wait = 0;
443430 memset(&res->l_lock_prmode, 0, sizeof(struct ocfs2_lock_stats));
444431 memset(&res->l_lock_exmode, 0, sizeof(struct ocfs2_lock_stats));
445432 }
....@@ -474,11 +461,28 @@
474461
475462 if (ret)
476463 stats->ls_fail++;
464
+
465
+ stats->ls_last = ktime_to_us(ktime_get_real());
477466 }
478467
479468 static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
480469 {
481470 lockres->l_lock_refresh++;
471
+}
472
+
473
+static inline void ocfs2_track_lock_wait(struct ocfs2_lock_res *lockres)
474
+{
475
+ struct ocfs2_mask_waiter *mw;
476
+
477
+ if (list_empty(&lockres->l_mask_waiters)) {
478
+ lockres->l_lock_wait = 0;
479
+ return;
480
+ }
481
+
482
+ mw = list_first_entry(&lockres->l_mask_waiters,
483
+ struct ocfs2_mask_waiter, mw_item);
484
+ lockres->l_lock_wait =
485
+ ktime_to_us(ktime_mono_to_real(mw->mw_lock_start));
482486 }
483487
484488 static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
....@@ -494,6 +498,9 @@
494498 {
495499 }
496500 static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
501
+{
502
+}
503
+static inline void ocfs2_track_lock_wait(struct ocfs2_lock_res *lockres)
497504 {
498505 }
499506 static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
....@@ -563,7 +570,7 @@
563570 mlog_bug_on_msg(1, "type: %d\n", type);
564571 ops = NULL; /* thanks, gcc */
565572 break;
566
- };
573
+ }
567574
568575 ocfs2_build_lock_name(type, OCFS2_I(inode)->ip_blkno,
569576 generation, res->l_name);
....@@ -692,6 +699,9 @@
692699 {
693700 struct ocfs2_lock_res *lockres = &osb->osb_trim_fs_lockres;
694701
702
+ /* Only one trimfs thread are allowed to work at the same time. */
703
+ mutex_lock(&osb->obs_trim_fs_mutex);
704
+
695705 ocfs2_lock_res_init_once(lockres);
696706 ocfs2_build_lock_name(OCFS2_LOCK_TYPE_TRIM_FS, 0, 0, lockres->l_name);
697707 ocfs2_lock_res_init_common(osb, lockres, OCFS2_LOCK_TYPE_TRIM_FS,
....@@ -704,6 +714,8 @@
704714
705715 ocfs2_simple_drop_lockres(osb, lockres);
706716 ocfs2_lock_res_free(lockres);
717
+
718
+ mutex_unlock(&osb->obs_trim_fs_mutex);
707719 }
708720
709721 static void ocfs2_orphan_scan_lock_res_init(struct ocfs2_lock_res *res,
....@@ -890,6 +902,7 @@
890902 list_del_init(&mw->mw_item);
891903 mw->mw_status = 0;
892904 complete(&mw->mw_complete);
905
+ ocfs2_track_lock_wait(lockres);
893906 }
894907 }
895908 static void lockres_or_flags(struct ocfs2_lock_res *lockres, unsigned long or)
....@@ -1401,6 +1414,7 @@
14011414 list_add_tail(&mw->mw_item, &lockres->l_mask_waiters);
14021415 mw->mw_mask = mask;
14031416 mw->mw_goal = goal;
1417
+ ocfs2_track_lock_wait(lockres);
14041418 }
14051419
14061420 /* returns 0 if the mw that was removed was already satisfied, -EBUSY
....@@ -1417,6 +1431,7 @@
14171431
14181432 list_del_init(&mw->mw_item);
14191433 init_completion(&mw->mw_complete);
1434
+ ocfs2_track_lock_wait(lockres);
14201435 }
14211436
14221437 return ret;
....@@ -1678,7 +1693,7 @@
16781693 spin_unlock_irqrestore(&lockres->l_lock, flags);
16791694 #ifdef CONFIG_DEBUG_LOCK_ALLOC
16801695 if (lockres->l_lockdep_map.key != NULL)
1681
- rwsem_release(&lockres->l_lockdep_map, 1, caller_ip);
1696
+ rwsem_release(&lockres->l_lockdep_map, caller_ip);
16821697 #endif
16831698 }
16841699
....@@ -2124,15 +2139,15 @@
21242139 }
21252140
21262141 #define OCFS2_SEC_BITS 34
2127
-#define OCFS2_SEC_SHIFT (64 - 34)
2142
+#define OCFS2_SEC_SHIFT (64 - OCFS2_SEC_BITS)
21282143 #define OCFS2_NSEC_MASK ((1ULL << OCFS2_SEC_SHIFT) - 1)
21292144
21302145 /* LVB only has room for 64 bits of time here so we pack it for
21312146 * now. */
2132
-static u64 ocfs2_pack_timespec(struct timespec *spec)
2147
+static u64 ocfs2_pack_timespec(struct timespec64 *spec)
21332148 {
21342149 u64 res;
2135
- u64 sec = spec->tv_sec;
2150
+ u64 sec = clamp_t(time64_t, spec->tv_sec, 0, 0x3ffffffffull);
21362151 u32 nsec = spec->tv_nsec;
21372152
21382153 res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK);
....@@ -2148,7 +2163,6 @@
21482163 struct ocfs2_inode_info *oi = OCFS2_I(inode);
21492164 struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
21502165 struct ocfs2_meta_lvb *lvb;
2151
- struct timespec ts;
21522166
21532167 lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
21542168
....@@ -2169,15 +2183,12 @@
21692183 lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
21702184 lvb->lvb_imode = cpu_to_be16(inode->i_mode);
21712185 lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
2172
- ts = timespec64_to_timespec(inode->i_atime);
21732186 lvb->lvb_iatime_packed =
2174
- cpu_to_be64(ocfs2_pack_timespec(&ts));
2175
- ts = timespec64_to_timespec(inode->i_ctime);
2187
+ cpu_to_be64(ocfs2_pack_timespec(&inode->i_atime));
21762188 lvb->lvb_ictime_packed =
2177
- cpu_to_be64(ocfs2_pack_timespec(&ts));
2178
- ts = timespec64_to_timespec(inode->i_mtime);
2189
+ cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
21792190 lvb->lvb_imtime_packed =
2180
- cpu_to_be64(ocfs2_pack_timespec(&ts));
2191
+ cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
21812192 lvb->lvb_iattr = cpu_to_be32(oi->ip_attr);
21822193 lvb->lvb_idynfeatures = cpu_to_be16(oi->ip_dyn_features);
21832194 lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
....@@ -2186,7 +2197,7 @@
21862197 mlog_meta_lvb(0, lockres);
21872198 }
21882199
2189
-static void ocfs2_unpack_timespec(struct timespec *spec,
2200
+static void ocfs2_unpack_timespec(struct timespec64 *spec,
21902201 u64 packed_time)
21912202 {
21922203 spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT;
....@@ -2195,7 +2206,6 @@
21952206
21962207 static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
21972208 {
2198
- struct timespec ts;
21992209 struct ocfs2_inode_info *oi = OCFS2_I(inode);
22002210 struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
22012211 struct ocfs2_meta_lvb *lvb;
....@@ -2223,15 +2233,12 @@
22232233 i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
22242234 inode->i_mode = be16_to_cpu(lvb->lvb_imode);
22252235 set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
2226
- ocfs2_unpack_timespec(&ts,
2236
+ ocfs2_unpack_timespec(&inode->i_atime,
22272237 be64_to_cpu(lvb->lvb_iatime_packed));
2228
- inode->i_atime = timespec_to_timespec64(ts);
2229
- ocfs2_unpack_timespec(&ts,
2238
+ ocfs2_unpack_timespec(&inode->i_mtime,
22302239 be64_to_cpu(lvb->lvb_imtime_packed));
2231
- inode->i_mtime = timespec_to_timespec64(ts);
2232
- ocfs2_unpack_timespec(&ts,
2240
+ ocfs2_unpack_timespec(&inode->i_ctime,
22332241 be64_to_cpu(lvb->lvb_ictime_packed));
2234
- inode->i_ctime = timespec_to_timespec64(ts);
22352242 spin_unlock(&oi->ip_lock);
22362243 }
22372244
....@@ -2507,9 +2514,7 @@
25072514 ocfs2_inode_unlock(inode, ex);
25082515 }
25092516
2510
- if (local_bh)
2511
- brelse(local_bh);
2512
-
2517
+ brelse(local_bh);
25132518 return status;
25142519 }
25152520
....@@ -2592,8 +2597,7 @@
25922597 *level = 1;
25932598 if (ocfs2_should_update_atime(inode, vfsmnt))
25942599 ocfs2_update_inode_atime(inode, bh);
2595
- if (bh)
2596
- brelse(bh);
2600
+ brelse(bh);
25972601 } else
25982602 *level = 0;
25992603
....@@ -3026,7 +3030,7 @@
30263030
30273031 kref_init(&dlm_debug->d_refcnt);
30283032 INIT_LIST_HEAD(&dlm_debug->d_lockres_tracking);
3029
- dlm_debug->d_locking_state = NULL;
3033
+ dlm_debug->d_filter_secs = 0;
30303034 out:
30313035 return dlm_debug;
30323036 }
....@@ -3117,16 +3121,42 @@
31173121 * - Lock stats printed
31183122 * New in version 3
31193123 * - Max time in lock stats is in usecs (instead of nsecs)
3124
+ * New in version 4
3125
+ * - Add last pr/ex unlock times and first lock wait time in usecs
31203126 */
3121
-#define OCFS2_DLM_DEBUG_STR_VERSION 3
3127
+#define OCFS2_DLM_DEBUG_STR_VERSION 4
31223128 static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
31233129 {
31243130 int i;
31253131 char *lvb;
31263132 struct ocfs2_lock_res *lockres = v;
3133
+#ifdef CONFIG_OCFS2_FS_STATS
3134
+ u64 now, last;
3135
+ struct ocfs2_dlm_debug *dlm_debug =
3136
+ ((struct ocfs2_dlm_seq_priv *)m->private)->p_dlm_debug;
3137
+#endif
31273138
31283139 if (!lockres)
31293140 return -EINVAL;
3141
+
3142
+#ifdef CONFIG_OCFS2_FS_STATS
3143
+ if (!lockres->l_lock_wait && dlm_debug->d_filter_secs) {
3144
+ now = ktime_to_us(ktime_get_real());
3145
+ if (lockres->l_lock_prmode.ls_last >
3146
+ lockres->l_lock_exmode.ls_last)
3147
+ last = lockres->l_lock_prmode.ls_last;
3148
+ else
3149
+ last = lockres->l_lock_exmode.ls_last;
3150
+ /*
3151
+ * Use d_filter_secs field to filter lock resources dump,
3152
+ * the default d_filter_secs(0) value filters nothing,
3153
+ * otherwise, only dump the last N seconds active lock
3154
+ * resources.
3155
+ */
3156
+ if (div_u64(now - last, 1000000) > dlm_debug->d_filter_secs)
3157
+ return 0;
3158
+ }
3159
+#endif
31303160
31313161 seq_printf(m, "0x%x\t", OCFS2_DLM_DEBUG_STR_VERSION);
31323162
....@@ -3169,6 +3199,9 @@
31693199 # define lock_max_prmode(_l) ((_l)->l_lock_prmode.ls_max)
31703200 # define lock_max_exmode(_l) ((_l)->l_lock_exmode.ls_max)
31713201 # define lock_refresh(_l) ((_l)->l_lock_refresh)
3202
+# define lock_last_prmode(_l) ((_l)->l_lock_prmode.ls_last)
3203
+# define lock_last_exmode(_l) ((_l)->l_lock_exmode.ls_last)
3204
+# define lock_wait(_l) ((_l)->l_lock_wait)
31723205 #else
31733206 # define lock_num_prmode(_l) (0)
31743207 # define lock_num_exmode(_l) (0)
....@@ -3179,6 +3212,9 @@
31793212 # define lock_max_prmode(_l) (0)
31803213 # define lock_max_exmode(_l) (0)
31813214 # define lock_refresh(_l) (0)
3215
+# define lock_last_prmode(_l) (0ULL)
3216
+# define lock_last_exmode(_l) (0ULL)
3217
+# define lock_wait(_l) (0ULL)
31823218 #endif
31833219 /* The following seq_print was added in version 2 of this output */
31843220 seq_printf(m, "%u\t"
....@@ -3189,7 +3225,10 @@
31893225 "%llu\t"
31903226 "%u\t"
31913227 "%u\t"
3192
- "%u\t",
3228
+ "%u\t"
3229
+ "%llu\t"
3230
+ "%llu\t"
3231
+ "%llu\t",
31933232 lock_num_prmode(lockres),
31943233 lock_num_exmode(lockres),
31953234 lock_num_prmode_failed(lockres),
....@@ -3198,7 +3237,10 @@
31983237 lock_total_exmode(lockres),
31993238 lock_max_prmode(lockres),
32003239 lock_max_exmode(lockres),
3201
- lock_refresh(lockres));
3240
+ lock_refresh(lockres),
3241
+ lock_last_prmode(lockres),
3242
+ lock_last_exmode(lockres),
3243
+ lock_wait(lockres));
32023244
32033245 /* End the line */
32043246 seq_printf(m, "\n");
....@@ -3252,36 +3294,24 @@
32523294 .llseek = seq_lseek,
32533295 };
32543296
3255
-static int ocfs2_dlm_init_debug(struct ocfs2_super *osb)
3297
+static void ocfs2_dlm_init_debug(struct ocfs2_super *osb)
32563298 {
3257
- int ret = 0;
32583299 struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug;
32593300
3260
- dlm_debug->d_locking_state = debugfs_create_file("locking_state",
3261
- S_IFREG|S_IRUSR,
3262
- osb->osb_debug_root,
3263
- osb,
3264
- &ocfs2_dlm_debug_fops);
3265
- if (!dlm_debug->d_locking_state) {
3266
- ret = -EINVAL;
3267
- mlog(ML_ERROR,
3268
- "Unable to create locking state debugfs file.\n");
3269
- goto out;
3270
- }
3301
+ debugfs_create_file("locking_state", S_IFREG|S_IRUSR,
3302
+ osb->osb_debug_root, osb, &ocfs2_dlm_debug_fops);
32713303
3304
+ debugfs_create_u32("locking_filter", 0600, osb->osb_debug_root,
3305
+ &dlm_debug->d_filter_secs);
32723306 ocfs2_get_dlm_debug(dlm_debug);
3273
-out:
3274
- return ret;
32753307 }
32763308
32773309 static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
32783310 {
32793311 struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug;
32803312
3281
- if (dlm_debug) {
3282
- debugfs_remove(dlm_debug->d_locking_state);
3313
+ if (dlm_debug)
32833314 ocfs2_put_dlm_debug(dlm_debug);
3284
- }
32853315 }
32863316
32873317 int ocfs2_dlm_init(struct ocfs2_super *osb)
....@@ -3294,11 +3324,7 @@
32943324 goto local;
32953325 }
32963326
3297
- status = ocfs2_dlm_init_debug(osb);
3298
- if (status < 0) {
3299
- mlog_errno(status);
3300
- goto bail;
3301
- }
3327
+ ocfs2_dlm_init_debug(osb);
33023328
33033329 /* launch downconvert thread */
33043330 osb->dc_task = kthread_run(ocfs2_downconvert_thread, osb, "ocfs2dc-%s",
....@@ -3370,10 +3396,12 @@
33703396 ocfs2_lock_res_free(&osb->osb_nfs_sync_lockres);
33713397 ocfs2_lock_res_free(&osb->osb_orphan_scan.os_lockres);
33723398
3373
- ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
3374
- osb->cconn = NULL;
3399
+ if (osb->cconn) {
3400
+ ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
3401
+ osb->cconn = NULL;
33753402
3376
- ocfs2_dlm_shutdown_debug(osb);
3403
+ ocfs2_dlm_shutdown_debug(osb);
3404
+ }
33773405 }
33783406
33793407 static int ocfs2_drop_lock(struct ocfs2_super *osb,
....@@ -4391,7 +4419,6 @@
43914419
43924420 static int ocfs2_downconvert_thread(void *arg)
43934421 {
4394
- int status = 0;
43954422 struct ocfs2_super *osb = arg;
43964423
43974424 /* only quit once we've been asked to stop and there is no more
....@@ -4409,7 +4436,7 @@
44094436 }
44104437
44114438 osb->dc_task = NULL;
4412
- return status;
4439
+ return 0;
44134440 }
44144441
44154442 void ocfs2_wake_downconvert_thread(struct ocfs2_super *osb)