For 2.6.35
Subsystems (3)
cover For 2.6.35
I'd like these patches to be considered for 2.6.35.
The patches posted last week that add kobjects for the NLM host and NSM handle caches are also candidates for 2.6.35. However, I'd like to have a clear plan for how statd will use this new API before they are committed upstream, to avoid kernel-user space API churn down the road.
The first patch in the present series is the previously posted fix for NFSv4 rsize and wsize. If this patch hasn't already been accepted for 2.6.34 and prior kernels, please consider it for 2.6.35.
The final four patches in this series are meant to improve the precision of RPC RTTs used for RTT estimation and reported via /proc/mountstats.
---
Chuck Lever (9):
SUNRPC: Replace jiffies-based metrics with ktime-based metrics
ktime: introduce ktime_to_ms()
SUNRPC: RPC metrics and RTT estimator should use same RTT value
NFS: Calldata for nfs4_renew_done()
NFS: Squelch compiler warning in nfs_add_server_stats()
NFS: Clean up fscache_uniq mount option
NFS: Squelch compiler warning
SUNRPC: Trivial cleanups in include/linux/sunrpc/xdr.h
NFS: rsize and wsize settings ignored on v4 mounts
fs/nfs/client.c | 2 ++ fs/nfs/fscache.c | 3 ++- fs/nfs/iostat.h | 6 +++--- fs/nfs/nfs4proc.c | 26 ++++++++++++++++++++------ fs/nfs/super.c | 18 +++++++++--------- include/linux/ktime.h | 10 ++++++++-- include/linux/sunrpc/metrics.h | 7 ++++--- include/linux/sunrpc/sched.h | 5 +++-- include/linux/sunrpc/xdr.h | 8 +++++--- include/linux/sunrpc/xprt.h | 4 ++-- net/sunrpc/sched.c | 2 +- net/sunrpc/stats.c | 27 +++++++++------------------ net/sunrpc/xprt.c | 19 ++++++++----------- net/sunrpc/xprtsock.c | 1 - 14 files changed, 76 insertions(+), 62 deletions(-)
Signature · 1 line
Chuck Lever
A message that is not in the archive (sent off-list or not yet received): 20100421173628.2037.54635.stgit-bi+AKbBUZKY6gyzm1THtWbp2dZbC/[email protected]
PATCH 1/9 NFS: rsize and wsize settings ignored on v4 mounts
NFSv4 mounts ignore the rsize and wsize mount options, and always use the default transfer size for both. This seems to be because all NFSv4 mounts are now cloned, and the cloning logic doesn't copy the rsize and wsize settings from the parent nfs_server.
I tested Fedora's 2.6.32.11-99 and it seems to have this problem as well, so I'm guessing that .33, .32, and perhaps older kernels have this issue as well.
---
fs/nfs/client.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
fs/nfs/client.c +2 -0
@@ -966,6 +966,8 @@ out_error:static void nfs_server_copy_userdata (struct nfs_server *target,struct nfs_server *source) { target->flags = source->flags; + target->rsize = source->rsize; + target->wsize = source->wsize; target->acregmin = source->acregmin; target->acregmax = source->acregmax; target->acdirmin = source->acdirmin;
PATCH 2/9 SUNRPC: Trivial cleanups in include/linux/sunrpc/xdr.h
In reply to a message not in the archiveClean up: Update the documenting comment, and fix some minor white space issues.
---
include/linux/sunrpc/xdr.h | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
include/linux/sunrpc/xdr.h +5 -3
@@ -1,7 +1,10 @@/* -* include/linux/sunrpc/xdr.h +* XDR standard data types and function declarations * * Copyright (C) 1995-1997 Olaf Kirch <[email protected]> +* +* Based on: +* RFC 4506 "XDR: External Data Representation Standard", May 2006 */ #ifndef _SUNRPC_XDR_H_
@@ -62,7 +65,6 @@ struct xdr_buf {unsigned int buflen,/* Total length of storage buffer */ len;/* Length of XDR encoded message */ - };/*
@@ -178,7 +180,7 @@ struct xdr_array2_desc { };extern int xdr_decode_array2 (struct xdr_buf *buf,unsigned int base, -struct xdr_array2_desc *desc); +struct xdr_array2_desc *desc);extern int xdr_encode_array2 (struct xdr_buf *buf,unsigned int base,struct xdr_array2_desc *desc);
PATCH 3/9 NFS: Squelch compiler warning
In reply to a message not in the archiveSeen with -Wextra:
/home/cel/linux/fs/nfs/fscache.c: In function =E2=80=98__nfs_readpages_= from_fscache=E2=80=99:/home/cel/linux/fs/nfs/fscache.c:479: warning: comparison between signe= d and unsigned integer expressions
The comparison implicitly converts "int" to "unsigned", making it safe. But there's no need for the implicit type conversions here, and the dfprintk() already uses a "%u" formatter for "npages." Better to reduce confusion.
---
fs/nfs/fscache.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
fs/nfs/fscache.c +0 -0
@@ -467,7 +467,8 @@ int __nfs_readpages_from_fscache(struct nfs_open_co=
ntext *ctx,
struct list_head *pages, unsigned *nr_pages)
{
- int ret, npages =3D *nr_pages;
+ unsigned npages =3D *nr_pages;
+ int ret;
=20
dfprintk(FSCACHE, "NFS: nfs_getpages_from_fscache (0x%p/%u/0x%p)\n",
NFS_I(inode)->fscache, npages, inode);
PATCH 4/9 NFS: Clean up fscache_uniq mount option
In reply to a message not in the archiveClean up: fscache_uniq takes a string, so it should be included with the other string mount option definitions, by convention.
---
fs/nfs/super.c | 18 +++++++++--------- 1 files changed, 9 insertions(+), 9 deletions(-)
fs/nfs/super.c +9 -9
@@ -141,7 +141,6 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_resvport, "resvport" }, { Opt_noresvport, "noresvport" }, { Opt_fscache, "fsc" }, - { Opt_fscache_uniq, "fsc=%s" }, { Opt_nofscache, "nofsc" }, { Opt_port, "port=%s" },
@@ -171,6 +170,7 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_mountaddr, "mountaddr=%s" }, { Opt_lookupcache, "lookupcache=%s" }, + { Opt_fscache_uniq, "fsc=%s" }, { Opt_err, NULL } };
@@ -1046,14 +1046,6 @@ static int nfs_parse_mount_options(char *raw,kfree (mnt->fscache_uniq); mnt->fscache_uniq =NULL ;break ; -case Opt_fscache_uniq: - string =match_strdup (args); -if (!string) - goto out_nomem; -kfree (mnt->fscache_uniq); - mnt->fscache_uniq = string; - mnt->options |=NFS_OPTION_FSCACHE ; -break ;/* * options that take numeric values
@@ -1384,6 +1376,14 @@ static int nfs_parse_mount_options(char *raw,return 0 ; };break ; +case Opt_fscache_uniq: + string =match_strdup (args); +if (string ==NULL ) + goto out_nomem; +kfree (mnt->fscache_uniq); + mnt->fscache_uniq = string; + mnt->options |=NFS_OPTION_FSCACHE ; +break ;/* * Special options
PATCH 5/9 NFS: Squelch compiler warning in nfs_add_server_stats()
In reply to a message not in the archiveClean up:
fs/nfs/iostat.h: In function =E2=80=98nfs_add_server_stats=E2=80=99:fs/nfs/iostat.h:41: warning: comparison between signed and unsigned int= eger expressionsfs/nfs/iostat.h:41: warning: comparison between signed and unsigned int= eger expressionsfs/nfs/iostat.h:41: warning: comparison between signed and unsigned int= eger expressionsfs/nfs/iostat.h:41: warning: comparison between signed and unsigned int= eger expressions
Commit fce22848 replaced the open-coded per-cpu logic in several functions in fs/nfs/iostat.h with a single invocation of this_cpu_ptr(). This macro assumes its second argument is signed, not unsigned.
---
fs/nfs/iostat.h | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
fs/nfs/iostat.h +0 -0
@@ -36,14 +36,14 @@ static inline void nfs_inc_stats(const struct inode= *inode,
=20
static inline void nfs_add_server_stats(const struct nfs_server *serve=
r,
enum nfs_stat_bytecounters stat,
- unsigned long addend)
+ long addend)
{
this_cpu_add(server->io_stats->bytes[stat], addend);
}
=20
static inline void nfs_add_stats(const struct inode *inode,
enum nfs_stat_bytecounters stat,
- unsigned long addend)
+ long addend)
{
nfs_add_server_stats(NFS_SERVER(inode), stat, addend);
}
@@ -51,7 +51,7 @@ static inline void nfs_add_stats(const struct inode *= inode,
#ifdef CONFIG_NFS_FSCACHE
static inline void nfs_add_fscache_stats(struct inode *inode,
enum nfs_stat_fscachecounters stat,
- unsigned long addend)
+ long addend)
{
this_cpu_add(NFS_SERVER(inode)->io_stats->fscache[stat], addend);
}
PATCH 6/9 NFS: Calldata for nfs4_renew_done()
In reply to a message not in the archiveI'm about to change task->tk_start from a jiffies value to a ktime_t value in order to make RPC RTT reporting more precise.
Recently (commit dc96aef9) nfs4_renew_done() started to reference task->tk_start so that a jiffies value no longer had to be passed from nfs4_proc_async_renew(). This allowed the calldata to point to an nfs_client instead.
Changing task->tk_start to a ktime_t value makes it effectively useless for renew timestamps, so we need to restore the pre-dc96aef9 logic that provided a jiffies "start" timestamp to nfs4_renew_done().
Both an nfs_client pointer and a timestamp need to be passed to nfs4_renew_done(), so create a new nfs_renewdata structure that contains both, resembling what is already done for delegreturn, lock, and unlock.
---
fs/nfs/nfs4proc.c | 26 ++++++++++++++++++++------ 1 files changed, 20 insertions(+), 6 deletions(-)
fs/nfs/nfs4proc.c +20 -6
@@ -3146,23 +3146,31 @@ static void nfs4_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT ]; } +struct nfs4_renewdata { +struct nfs_client *client; +unsigned long timestamp; +}; +/* * nfs4_proc_async_renew(): This is not one of the nfs_rpc_ops; it is a special * standalone procedure for queueing an asynchronous RENEW. */ -static void nfs4_renew_release (void *data) +static void nfs4_renew_release (void *calldata) { -struct nfs_client *clp = data; +struct nfs4_renewdata *data = calldata; +struct nfs_client *clp = data->client;if (atomic_read (&clp->cl_count) >1 )nfs4_schedule_state_renewal (clp);nfs_put_client (clp); +kfree (data); } -static void nfs4_renew_done (struct rpc_task *task,void *data) +static void nfs4_renew_done (struct rpc_task *task,void *calldata) { -struct nfs_client *clp = data; -unsigned long timestamp = task->tk_start; +struct nfs4_renewdata *data = calldata; +struct nfs_client *clp = data->client; +unsigned long timestamp = data->timestamp;if (task->tk_status <0 ) {/* Unless we're shutting down, schedule state recovery! */
@@ -3188,11 +3196,17 @@ int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred) .rpc_argp = clp, .rpc_cred = cred, }; +struct nfs4_renewdata *data;if (!atomic_inc_not_zero (&clp->cl_count))return -EIO ; + data =kmalloc (sizeof (*data),GFP_KERNEL ); +if (data ==NULL ) +return -ENOMEM ; + data->client = clp; + data->timestamp = jiffies;return rpc_call_async (clp->cl_rpcclient, &msg,RPC_TASK_SOFT , - &nfs4_renew_ops, clp); + &nfs4_renew_ops, (void *)data); }int nfs4_proc_renew (struct nfs_client *clp,struct rpc_cred *cred)
PATCH 7/9 SUNRPC: RPC metrics and RTT estimator should use same RTT value
In reply to a message not in the archiveCompute an RPC request's RTT once, and use that value both for reporting RPC metrics, and for adjusting the RTT context used by the RPC client's RTT estimator algorithm.
---
include/linux/sunrpc/xprt.h | 1 - net/sunrpc/xprt.c | 13 ++++--------- net/sunrpc/xprtsock.c | 1 - 3 files changed, 4 insertions(+), 11 deletions(-)
include/linux/sunrpc/xprt.h +0 -1
@@ -294,7 +294,6 @@ void xprt_set_retrans_timeout_rtt(struct rpc_task *task);void xprt_wake_pending_tasks (struct rpc_xprt *xprt,int status);void xprt_wait_for_buffer_space (struct rpc_task *task,rpc_action action);void xprt_write_space (struct rpc_xprt *xprt); -void xprt_update_rtt (struct rpc_task *task);void xprt_adjust_cwnd (struct rpc_task *task,int result);struct rpc_rqst *xprt_lookup_rqst (struct rpc_xprt *xprt,__be32 xid);void xprt_complete_rqst (struct rpc_task *task,int copied);
net/sunrpc/xprt.c +4 -9
@@ -771,12 +771,7 @@ struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, __be32 xid) }EXPORT_SYMBOL_GPL (xprt_lookup_rqst); -/** -* xprt_update_rtt - update an RPC client's RTT state after receiving a reply -* @task: RPC request that recently completed -* -*/ -void xprt_update_rtt (struct rpc_task *task) +static void xprt_update_rtt (struct rpc_task *task) {struct rpc_rqst *req = task->tk_rqstp;struct rpc_rtt *rtt = task->tk_client->cl_rtt;
@@ -784,12 +779,10 @@ void xprt_update_rtt(struct rpc_task *task)if (timer) {if (req->rq_ntrans ==1 ) -rpc_update_rtt (rtt, timer, - (long )jiffies - req->rq_xtime); +rpc_update_rtt (rtt, timer, task->tk_rtt);rpc_set_timeo (rtt, timer, req->rq_ntrans -1 ); } } -EXPORT_SYMBOL_GPL (xprt_update_rtt);/** * xprt_complete_rqst - called when reply processing is complete
@@ -808,6 +801,8 @@ void xprt_complete_rqst(struct rpc_task *task, int copied) xprt->stat.recvs++; task->tk_rtt = (long )jiffies - req->rq_xtime; +if (xprt->ops->timer !=NULL ) +xprt_update_rtt (task);list_del_init (&req->rq_list); req->rq_private_buf.len = copied;
net/sunrpc/xprtsock.c +0 -1
@@ -858,7 +858,6 @@ static void xs_udp_data_ready(struct sock *sk, int len)dst_confirm (skb_dst (skb));xprt_adjust_cwnd (task, copied); -xprt_update_rtt (task);xprt_complete_rqst (task, copied); out_unlock:
PATCH 8/9 ktime: introduce ktime_to_ms()
In reply to a message not in the archiveTo report ktime statistics to user space in milliseconds, a new helper is required.
When considering how to do this conversion, I didn't immediately see why the extra step of converting ktime to a timeval was needed. To make that more clear, introduce a couple of large comments.
---
include/linux/ktime.h | 10 ++++++++-- 1 files changed, 8 insertions(+), 2 deletions(-)
include/linux/ktime.h +8 -2
@@ -130,7 +130,7 @@ static inline ktime_t timeval_to_ktime(struct timeval tv)/* Convert ktime_t to nanoseconds - NOP in the scalar storage format: */ #define ktime_to_ns (kt) ((kt).tv64) -#else +#else /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */ /* * Helper macros/inlines to get the ktime_t math right in the timespec
@@ -275,7 +275,7 @@ static inline s64 ktime_to_ns(const ktime_t kt) return (s64) kt.tv.sec * NSEC_PER_SEC + kt.tv.nsec; } -#endif +#endif /* !((BITS_PER_LONG == 64) || defined(CONFIG_KTIME_SCALAR)) */ /** * ktime_equal - Compares two ktime_t variables to see if they are equal
@@ -295,6 +295,12 @@ static inline s64 ktime_to_us(const ktime_t kt)return (s64 ) tv.tv_sec *USEC_PER_SEC + tv.tv_usec; } +static inline s64 ktime_to_ms (const ktime_t kt) +{ +struct timeval tv =ktime_to_timeval (kt); +return (s64 ) tv.tv_sec *MSEC_PER_SEC + tv.tv_usec /USEC_PER_MSEC ; +} +static inline s64 ktime_us_delta (const ktime_t later,const ktime_t earlier) {return ktime_to_us (ktime_sub (later, earlier));
PATCH 9/9 SUNRPC: Replace jiffies-based metrics with ktime-based metrics
In reply to a message not in the archiveCurrently RPC performance metrics that tabulate elapsed time use jiffies time values. This is problematic on systems that use slow jiffies (for instance 100HZ systems built for paravirtualized environments). It is also a problem for computing precise latency statistics for advanced network transports, such as InfiniBand, that can have round-trip latencies significanly faster than a single clock tick.
For the RPC client, adopt the high resolution time stamp mechanism already used by the network layer and blktrace: ktime.
We use ktime format time stamps for all internal computations, and convert to milliseconds for presentation. As a result, we need only addition operations in the performance critical paths; multiply/divide is required only for presentation.
We could report RTT metrics in microseconds. In fact the mountstats format is versioned to accomodate exactly this kind of interface improvement.
For now, however, we'll stay with millisecond precision for presentation to maintain backwards compatibility with the handful of currently deployed user space tools. At a later point, we'll move to an API such as BDI_STATS where a finer timestamp precision can be reported.
---
include/linux/sunrpc/metrics.h | 7 ++++--- include/linux/sunrpc/sched.h | 5 +++-- include/linux/sunrpc/xprt.h | 3 ++- net/sunrpc/sched.c | 2 +- net/sunrpc/stats.c | 27 +++++++++------------------ net/sunrpc/xprt.c | 8 +++++--- 6 files changed, 24 insertions(+), 28 deletions(-)
include/linux/sunrpc/metrics.h +4 -3
@@ -26,6 +26,7 @@#define _LINUX_SUNRPC_METRICS_H#include <linux/seq_file.h> +#include <linux/ktime.h> #define RPC_IOSTATS_VERS "1.0"
@@ -58,9 +59,9 @@ struct rpc_iostats {* and the total time the request spent from init to release * are measured. */ -unsigned long long om_queue,/* jiffies queued for xmit */ - om_rtt,/* jiffies for RPC RTT */ - om_execute;/* jiffies for RPC execution */ +ktime_t om_queue,/* queued for xmit */ + om_rtt,/* RPC RTT */ + om_execute;/* RPC execution */ }____cacheline_aligned ;struct rpc_task ;
include/linux/sunrpc/sched.h +3 -2
@@ -10,6 +10,7 @@#define _LINUX_SUNRPC_SCHED_H_#include <linux/timer.h> +#include <linux/ktime.h> #include <linux/sunrpc/types.h> #include <linux/spinlock.h> #include <linux/wait.h>
@@ -80,8 +81,8 @@ struct rpc_task {unsigned short tk_timeouts;/* maj timeouts */ size_t tk_bytes_sent;/* total bytes sent */ -unsigned long tk_start;/* RPC task init timestamp */ -long tk_rtt;/* round-trip time (jiffies) */ +ktime_t tk_start,/* RPC task init timestamp */ + tk_rtt;/* round-trip time */ pid_t tk_owner;/* Process id for batching tasks */ unsigned char tk_priority : 2;/* Task priority */
include/linux/sunrpc/xprt.h +2 -1
@@ -13,6 +13,7 @@#include <linux/socket.h> #include <linux/in.h> #include <linux/kref.h> +#include <linux/ktime.h> #include <linux/sunrpc/sched.h> #include <linux/sunrpc/xdr.h> #include <linux/sunrpc/msg_prot.h>
@@ -94,7 +95,7 @@ struct rpc_rqst {*/ u32 rq_bytes_sent;/* Bytes we have sent */ -unsigned long rq_xtime;/* when transmitted */ +ktime_t rq_xtime;/* transmit time stamp */ int rq_ntrans;#if defined(CONFIG_NFS_V4_1 )
net/sunrpc/sched.c +1 -1
@@ -834,7 +834,7 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta }/* starting timestamp */ - task->tk_start = jiffies; + task->tk_start =ktime_get ();dprintk ("RPC: new task initialized, procpid %u\n" ,task_pid_nr (current));
net/sunrpc/stats.c +9 -18
@@ -144,7 +144,7 @@ void rpc_count_iostats(struct rpc_task *task)struct rpc_rqst *req = task->tk_rqstp;struct rpc_iostats *stats;struct rpc_iostats *op_metrics; -long rtt, execute, queue; +ktime_t delta;if (!task->tk_client || !task->tk_client->cl_metrics || !req)return ;
@@ -159,20 +159,13 @@ void rpc_count_iostats(struct rpc_task *task) op_metrics->om_bytes_sent += task->tk_bytes_sent; op_metrics->om_bytes_recv += req->rq_reply_bytes_recvd; - queue = (long )req->rq_xtime - task->tk_start; -if (queue <0 ) - queue = -queue; - op_metrics->om_queue += queue; + delta =ktime_sub (req->rq_xtime, task->tk_start); + op_metrics->om_queue =ktime_add (op_metrics->om_queue, delta); - rtt = task->tk_rtt; -if (rtt <0 ) - rtt = -rtt; - op_metrics->om_rtt += rtt; + op_metrics->om_rtt =ktime_add (op_metrics->om_rtt, task->tk_rtt); - execute = (long )jiffies - task->tk_start; -if (execute <0 ) - execute = -execute; - op_metrics->om_execute += execute; + delta =ktime_sub (ktime_get (), task->tk_start); + op_metrics->om_execute =ktime_add (op_metrics->om_execute, delta); } static void _print_name(struct seq_file *seq, unsigned int op,
@@ -186,8 +179,6 @@ static void _print_name(struct seq_file *seq, unsigned int op,seq_printf (seq,"\t%12u: " , op); } -#define MILLISECS_PER_JIFFY (1000 / HZ) -void rpc_print_iostats (struct seq_file *seq,struct rpc_clnt *clnt) {struct rpc_iostats *stats = clnt->cl_metrics;
@@ -214,9 +205,9 @@ void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) metrics->om_timeouts, metrics->om_bytes_sent, metrics->om_bytes_recv, - metrics->om_queue *MILLISECS_PER_JIFFY , - metrics->om_rtt *MILLISECS_PER_JIFFY , - metrics->om_execute * MILLISECS_PER_JIFFY); +ktime_to_ms (metrics->om_queue), +ktime_to_ms (metrics->om_rtt), + ktime_to_ms(metrics->om_execute)); } }EXPORT_SYMBOL_GPL (rpc_print_iostats);
net/sunrpc/xprt.c +5 -3
@@ -43,6 +43,7 @@#include <linux/interrupt.h> #include <linux/workqueue.h> #include <linux/net.h> +#include <linux/ktime.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/metrics.h>
@@ -776,10 +777,11 @@ static void xprt_update_rtt(struct rpc_task *task)struct rpc_rqst *req = task->tk_rqstp;struct rpc_rtt *rtt = task->tk_client->cl_rtt;unsigned timer = task->tk_msg.rpc_proc->p_timer; +long m =usecs_to_jiffies (ktime_to_us (task->tk_rtt));if (timer) {if (req->rq_ntrans ==1 ) -rpc_update_rtt (rtt, timer, task->tk_rtt); +rpc_update_rtt (rtt, timer, m);rpc_set_timeo (rtt, timer, req->rq_ntrans -1 ); } }
@@ -800,7 +802,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied) task->tk_pid, ntohl(req->rq_xid), copied); xprt->stat.recvs++; - task->tk_rtt = (long )jiffies - req->rq_xtime; + task->tk_rtt =ktime_sub (ktime_get (), req->rq_xtime);if (xprt->ops->timer !=NULL )xprt_update_rtt (task);
@@ -901,7 +903,7 @@ void xprt_transmit(struct rpc_task *task)return ; req->rq_connect_cookie = xprt->connect_cookie; - req->rq_xtime = jiffies; + req->rq_xtime =ktime_get (); status = xprt->ops->send_request (task);if (status !=0 ) { task->tk_status = status;