Skip to content

Commit

Permalink
SUNRPC: Cache deferral injection
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
chucklever committed May 19, 2022
1 parent 45cb795 commit 37324e6
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
18 changes: 17 additions & 1 deletion net/sunrpc/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions net/sunrpc/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ static void fail_sunrpc_init(void)

debugfs_create_bool("ignore-server-disconnect", S_IFREG | 0600, dir,
&fail_sunrpc.ignore_server_disconnect);

debugfs_create_bool("ignore-cache-wait", S_IFREG | 0600, dir,
&fail_sunrpc.ignore_cache_wait);
}
#else
static void fail_sunrpc_init(void)
Expand Down
2 changes: 1 addition & 1 deletion net/sunrpc/fail.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ struct fail_sunrpc_attr {
struct fault_attr attr;

bool ignore_client_disconnect;

bool ignore_server_disconnect;
bool ignore_cache_wait;
};

extern struct fail_sunrpc_attr fail_sunrpc;
Expand Down

0 comments on commit 37324e6

Please sign in to comment.