lockd: add some client-side tracepoints
authorJeff Layton <jlayton@kernel.org>
Fri, 3 Mar 2023 12:16:03 +0000 (07:16 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Wed, 26 Apr 2023 13:05:00 +0000 (09:05 -0400)
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/Makefile
fs/lockd/clntlock.c
fs/lockd/clntproc.c
fs/lockd/trace.c [new file with mode: 0644]
fs/lockd/trace.h [new file with mode: 0644]

index 6d5e83ed4476226a440624071584ccb7c8b1bff2..ac9f9d84510ec1524ff4362a7767371b2233df28 100644 (file)
@@ -3,10 +3,12 @@
 # Makefile for the linux lock manager stuff
 #
 
+ccflags-y += -I$(src)                  # needed for trace events
+
 obj-$(CONFIG_LOCKD) += lockd.o
 
-lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
-               svcshare.o svcproc.o svcsubs.o mon.o xdr.o
+lockd-objs-y += clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \
+               svcshare.o svcproc.o svcsubs.o mon.o trace.o xdr.o
 lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o
 lockd-objs-$(CONFIG_PROC_FS) += procfs.o
 lockd-objs                   := $(lockd-objs-y)
index c374ee072db360271f846215b08bacf9dab37142..e3972aa3045a38e5d9b30666dee0b7d1c2718eef 100644 (file)
 #include <linux/nfs_fs.h>
 #include <linux/sunrpc/addr.h>
 #include <linux/sunrpc/svc.h>
+#include <linux/sunrpc/svc_xprt.h>
 #include <linux/lockd/lockd.h>
 #include <linux/kthread.h>
 
+#include "trace.h"
+
 #define NLMDBG_FACILITY                NLMDBG_CLIENT
 
 /*
@@ -186,6 +189,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock)
                res = nlm_granted;
        }
        spin_unlock(&nlm_blocked_lock);
+       trace_nlmclnt_grant(lock, addr, svc_addr_len(addr), res);
        return res;
 }
 
index a14c9110719c5c3d4d43e2659994033e62fc0c97..fba6c7fa74747e9c411ed23917b744cc93c49ac3 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/lockd/lockd.h>
 
+#include "trace.h"
+
 #define NLMDBG_FACILITY                NLMDBG_CLIENT
 #define NLMCLNT_GRACE_WAIT     (5*HZ)
 #define NLMCLNT_POLL_TIMEOUT   (30*HZ)
@@ -451,6 +453,9 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl)
                        status = nlm_stat_to_errno(req->a_res.status);
        }
 out:
+       trace_nlmclnt_test(&req->a_args.lock,
+                          (const struct sockaddr *)&req->a_host->h_addr,
+                          req->a_host->h_addrlen, req->a_res.status);
        nlmclnt_release_call(req);
        return status;
 }
@@ -605,10 +610,16 @@ again:
        else
                status = nlm_stat_to_errno(resp->status);
 out:
+       trace_nlmclnt_lock(&req->a_args.lock,
+                          (const struct sockaddr *)&req->a_host->h_addr,
+                          req->a_host->h_addrlen, req->a_res.status);
        nlmclnt_release_call(req);
        return status;
 out_unlock:
        /* Fatal error: ensure that we remove the lock altogether */
+       trace_nlmclnt_lock(&req->a_args.lock,
+                          (const struct sockaddr *)&req->a_host->h_addr,
+                          req->a_host->h_addrlen, req->a_res.status);
        dprintk("lockd: lock attempt ended in fatal error.\n"
                "       Attempting to unlock.\n");
        fl_type = fl->fl_type;
@@ -704,6 +715,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
        /* What to do now? I'm out of my depth... */
        status = -ENOLCK;
 out:
+       trace_nlmclnt_unlock(&req->a_args.lock,
+                            (const struct sockaddr *)&req->a_host->h_addr,
+                            req->a_host->h_addrlen, req->a_res.status);
        nlmclnt_release_call(req);
        return status;
 }
diff --git a/fs/lockd/trace.c b/fs/lockd/trace.c
new file mode 100644 (file)
index 0000000..d9a6ff6
--- /dev/null
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0
+#define CREATE_TRACE_POINTS
+#include "trace.h"
diff --git a/fs/lockd/trace.h b/fs/lockd/trace.h
new file mode 100644 (file)
index 0000000..7461b13
--- /dev/null
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lockd
+
+#if !defined(_TRACE_LOCKD_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_LOCKD_H
+
+#include <linux/tracepoint.h>
+#include <linux/crc32.h>
+#include <linux/nfs.h>
+#include <linux/lockd/lockd.h>
+
+#ifdef CONFIG_LOCKD_V4
+#define NLM_STATUS_LIST                                        \
+       nlm_status_code(LCK_GRANTED)                    \
+       nlm_status_code(LCK_DENIED)                     \
+       nlm_status_code(LCK_DENIED_NOLOCKS)             \
+       nlm_status_code(LCK_BLOCKED)                    \
+       nlm_status_code(LCK_DENIED_GRACE_PERIOD)        \
+       nlm_status_code(DEADLCK)                        \
+       nlm_status_code(ROFS)                           \
+       nlm_status_code(STALE_FH)                       \
+       nlm_status_code(FBIG)                           \
+       nlm_status_code_end(FAILED)
+#else
+#define NLM_STATUS_LIST                                        \
+       nlm_status_code(LCK_GRANTED)                    \
+       nlm_status_code(LCK_DENIED)                     \
+       nlm_status_code(LCK_DENIED_NOLOCKS)             \
+       nlm_status_code(LCK_BLOCKED)                    \
+       nlm_status_code_end(LCK_DENIED_GRACE_PERIOD)
+#endif
+
+#undef nlm_status_code
+#undef nlm_status_code_end
+#define nlm_status_code(x)     TRACE_DEFINE_ENUM(NLM_##x);
+#define nlm_status_code_end(x) TRACE_DEFINE_ENUM(NLM_##x);
+
+NLM_STATUS_LIST
+
+#undef nlm_status_code
+#undef nlm_status_code_end
+#define nlm_status_code(x)     { NLM_##x, #x },
+#define nlm_status_code_end(x) { NLM_##x, #x }
+
+#define show_nlm_status(x)     __print_symbolic(x, NLM_STATUS_LIST)
+
+DECLARE_EVENT_CLASS(nlmclnt_lock_event,
+               TP_PROTO(
+                       const struct nlm_lock *lock,
+                       const struct sockaddr *addr,
+                       unsigned int addrlen,
+                       __be32 status
+               ),
+
+               TP_ARGS(lock, addr, addrlen, status),
+
+               TP_STRUCT__entry(
+                       __field(u32, oh)
+                       __field(u32, svid)
+                       __field(u32, fh)
+                       __field(unsigned long, status)
+                       __field(u64, start)
+                       __field(u64, len)
+                       __sockaddr(addr, addrlen)
+               ),
+
+               TP_fast_assign(
+                       __entry->oh = ~crc32_le(0xffffffff, lock->oh.data, lock->oh.len);
+                       __entry->svid = lock->svid;
+                       __entry->fh = nfs_fhandle_hash(&lock->fh);
+                       __entry->start = lock->lock_start;
+                       __entry->len = lock->lock_len;
+                       __entry->status = be32_to_cpu(status);
+                       __assign_sockaddr(addr, addr, addrlen);
+               ),
+
+               TP_printk(
+                       "addr=%pISpc oh=0x%08x svid=0x%08x fh=0x%08x start=%llu len=%llu status=%s",
+                       __get_sockaddr(addr), __entry->oh, __entry->svid,
+                       __entry->fh, __entry->start, __entry->len,
+                       show_nlm_status(__entry->status)
+               )
+);
+
+#define DEFINE_NLMCLNT_EVENT(name)                             \
+       DEFINE_EVENT(nlmclnt_lock_event, name,                  \
+                       TP_PROTO(                               \
+                               const struct nlm_lock *lock,    \
+                               const struct sockaddr *addr,    \
+                               unsigned int addrlen,           \
+                               __be32  status                  \
+                       ),                                      \
+                       TP_ARGS(lock, addr, addrlen, status))
+
+DEFINE_NLMCLNT_EVENT(nlmclnt_test);
+DEFINE_NLMCLNT_EVENT(nlmclnt_lock);
+DEFINE_NLMCLNT_EVENT(nlmclnt_unlock);
+DEFINE_NLMCLNT_EVENT(nlmclnt_grant);
+
+#endif /* _TRACE_LOCKD_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace
+#include <trace/define_trace.h>