--- /dev/null
+// rcu tapset
+// Copyright (C) 2013 Red Hat
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+%{
+#include <linux/rcupdate.h>
+#ifndef rcu_dereference_check
+#define STAP_ALWAYS_ACQUIRE_RCU_LOCK
+#endif
+%}
+
+function rcu_dereference:long (protected_pointer:long) %{ /* pure */
+ void *protected_pointer = (void *)(long)STAP_ARG_protected_pointer;
+ long fetched_value;
+
+#ifndef STAP_ALWAYS_ACQUIRE_RCU_LOCK
+ int lock_acquired = 0;
+
+ if (! rcu_read_lock_held()) {
+ rcu_read_lock();
+ lock_acquired = 1;
+ }
+#else
+ rcu_read_lock();
+#endif
+
+ fetched_value = (long)rcu_dereference(protected_pointer);
+
+#ifndef STAP_ALWAYS_ACQUIRE_RCU_LOCK
+ if (lock_acquired) {
+ rcu_read_unlock();
+ }
+#else
+ rcu_read_unlock();
+#endif
+ STAP_RETVALUE = fetched_value;
+%}
probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") !,
module("sunrpc").function("rpc_clone_client")
{
- servername = kernel_string($clnt->cl_server)
+ servername = kernel_string(@choose_defined($clnt->cl_server,
+ @cast(rcu_dereference($clnt->cl_xprt),
+ "struct rpc_xprt")->servername))
progname = kernel_string($clnt->cl_protname)
prog = prog_from_clnt($clnt)
vers = vers_from_clnt($clnt)
probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") !,
module("sunrpc").function("rpc_shutdown_client")
{
- servername = kernel_string($clnt->cl_server)
+ servername = kernel_string(@choose_defined($clnt->cl_server,
+ @cast(rcu_dereference($clnt->cl_xprt),
+ "struct rpc_xprt")->servername))
progname = kernel_string($clnt->cl_protname)
prog = prog_from_clnt($clnt)
vers = vers_from_clnt($clnt)
kernel.function("rpc_bind_new_program") !,
module("sunrpc").function("rpc_bind_new_program")
{
- servername = kernel_string($old->cl_server)
+ servername = kernel_string(@choose_defined($old->cl_server,
+ @cast(rcu_dereference($old->cl_xprt),
+ "struct rpc_xprt")->servername))
old_progname = kernel_string($old->cl_protname)
old_prog = prog_from_clnt($old)
old_vers = vers_from_clnt($old)
probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") !,
module("sunrpc").function("rpc_call_sync")
{
- servername = kernel_string($clnt->cl_server)
+ servername = kernel_string(@choose_defined($clnt->cl_server,
+ @cast(rcu_dereference($clnt->cl_xprt),
+ "struct rpc_xprt")->servername))
progname = kernel_string($clnt->cl_protname)
prog = prog_from_clnt($clnt)
vers = vers_from_clnt($clnt)
probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") !,
module("sunrpc").function("rpc_call_async")
{
- servername = kernel_string($clnt->cl_server)
+ servername = kernel_string(@choose_defined($clnt->cl_server,
+ @cast(rcu_dereference($clnt->cl_xprt),
+ "struct rpc_xprt")->servername))
progname = kernel_string($clnt->cl_protname)
prog = prog_from_clnt($clnt)
vers = vers_from_clnt($clnt)
probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") !,
module("sunrpc").function("rpc_restart_call")
{
- servername = kernel_string($task->tk_client->cl_server)
+ servername = kernel_string(@choose_defined($task->tk_client->cl_server,
+ @cast(rcu_dereference($task->tk_client->cl_xprt),
+ "struct rpc_xprt")->servername))
prog = prog_from_clnt($task->tk_client)
xid = $task->tk_rqstp->rq_xid
tk_pid = $task->tk_pid