aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/cache.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2022-03-31 15:30:10 -0400
committerChuck Lever <chuck.lever@oracle.com>2022-05-19 12:25:38 -0400
commit37324e6bb120bc3cb7cbaa87512ff3a93dbcf5c4 (patch)
tree34bacc7faeb7ad7e0eb5e7f960fe76b67c1f0c58 /net/sunrpc/cache.c
parentSUNRPC: Clean up svc_deferred_class trace events (diff)
downloadlinux-dev-37324e6bb120bc3cb7cbaa87512ff3a93dbcf5c4.tar.xz
linux-dev-37324e6bb120bc3cb7cbaa87512ff3a93dbcf5c4.zip
SUNRPC: Cache deferral injection
Cache deferral injection stress-tests the cache deferral logic as well as upper layer protocol deferred request handlers. This facility is for developers and professional testers to ensure coverage of the rqst deferral code paths. To date, we haven't had an adequate way to ensure these code paths are covered during testing, short of temporary code changes to force their use. A file called /sys/kernel/debug/fail_sunrpc/ignore-cache-wait enables administrators to disable cache deferral injection while allowing other types of sunrpc errors to be injected. The default setting is that cache deferral injection is enabled (ignore=false). To enable support for cache deferral injection, CONFIG_FAULT_INJECTION, CONFIG_FAULT_INJECTION_DEBUG_FS, and CONFIG_SUNRPC_DEBUG must all be set to "Y". Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'net/sunrpc/cache.c')
-rw-r--r--net/sunrpc/cache.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index bb1177395b99..c3c693b51c94 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -33,7 +33,9 @@
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/rpc_pipe_fs.h>
#include <trace/events/sunrpc.h>
+
#include "netns.h"
+#include "fail.h"
#define RPCDBG_FACILITY RPCDBG_CACHE
@@ -688,16 +690,30 @@ static void cache_limit_defers(void)
discard->revisit(discard, 1);
}
+#if IS_ENABLED(CONFIG_FAIL_SUNRPC)
+static inline bool cache_defer_immediately(void)
+{
+ return !fail_sunrpc.ignore_cache_wait &&
+ should_fail(&fail_sunrpc.attr, 1);
+}
+#else
+static inline bool cache_defer_immediately(void)
+{
+ return false;
+}
+#endif
+
/* Return true if and only if a deferred request is queued. */
static bool cache_defer_req(struct cache_req *req, struct cache_head *item)
{
struct cache_deferred_req *dreq;
- if (req->thread_wait) {
+ if (!cache_defer_immediately()) {
cache_wait_req(req, item);
if (!test_bit(CACHE_PENDING, &item->flags))
return false;
}
+
dreq = req->defer(req);
if (dreq == NULL)
return false;