mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Chuck Lever did a bunch of work on nfsd tracepoints, on RDMA, and on
server xdr decoding (with an eye towards eliminating a data copy in the RDMA case). I did some refactoring of the delegation code in preparation for eliminating some delegation self-conflicts and implementing write delegations. -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJaxi5LAAoJECebzXlCjuG+deAQAL9NHsv6bIydkE6wX305c/bR gm73yryF1kfOuHmiLq15mrljiKyCEbRSPqzzM8k2TkywHhyvOLEjxHbhZnwDyQec DaZUzWLKNkK64UFXEvTKyNwfGObwsGQ+QLkV7N9mF3Ps9M9/u2vMHKQypvA9hJ7z DGN7MO7Ud7N0Viu03vp4m+p7gypoWGFj6Sh1QAkR/7TE/supcS+qqOWU4vLpYFhu /l2gJym59FWqHajwqs0Qu9LpHfsEx5HySZbj7GczbGRMka3y/AnjgnngcriP+63B ZcPpqSdD4Yeq1OJklU5Wicy+u54rFkA9VE1EArrC9RAEwav6iMhhhaESpRH2JFJE SO7cgUSCb2+65XgeSBfDygn+09PcN+eRF3sxXkQpHKsozQOH+qdyr7F4/ePunwi8 Ah7pIkczRUrj7gMmlNOg97wpHbffO4YnpRESA934qf7MMHRQwDsEkl512kFAyadZ g1DI3iByfUpBQvRWJSLasyjyWUqRZDMmyO3yi3i/08sMI3XE1IOWpNkJAooNYC1X 1FCDn1VXlTdcmC8yw6Da1L05PCVf25tSjpYQZ6r25KtrVi9iBOGV741vmyVMvDEw OwUuVatRd+AY+YJ6iUraNH4SlnHWZ/qKDFJECWbrG/4uUHyo8FIXGAgL8RgtbS8+ fQeRjaDyhHD0XH7TJ10x =fJI1 -----END PGP SIGNATURE----- Merge tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux Pull nfsd updates from Bruce Fields: "Chuck Lever did a bunch of work on nfsd tracepoints, on RDMA, and on server xdr decoding (with an eye towards eliminating a data copy in the RDMA case). I did some refactoring of the delegation code in preparation for eliminating some delegation self-conflicts and implementing write delegations" * tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux: (40 commits) nfsd: fix incorrect umasks sunrpc: remove incorrect HMAC request initialization NFSD: Clean up legacy NFS SYMLINK argument XDR decoders NFSD: Clean up legacy NFS WRITE argument XDR decoders nfsd: Trace NFSv4 COMPOUND execution nfsd: Add I/O trace points in the NFSv4 read proc nfsd: Add I/O trace points in the NFSv4 write path nfsd: Add "nfsd_" to trace point names nfsd: Record request byte count, not count of vectors nfsd: Fix NFSD trace points svc: Report xprt dequeue latency sunrpc: Report per-RPC execution stats sunrpc: Re-purpose trace_svc_process sunrpc: Save remote presentation address in svc_xprt for trace events sunrpc: Simplify trace_svc_recv sunrpc: Simplify do_enqueue tracing sunrpc: Move trace_svc_xprt_dequeue() sunrpc: Update show_svc_xprt_flags() to include recently added flags svc: Simplify ->xpo_secure_port sunrpc: Remove unneeded pointer dereference ...
This commit is contained in:
commit
5e4d659713
31 changed files with 721 additions and 515 deletions
|
|
@ -237,9 +237,6 @@ make_checksum_hmac_md5(struct krb5_ctx *kctx, char *header, int hdrlen,
|
|||
|
||||
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL);
|
||||
|
||||
err = crypto_ahash_init(req);
|
||||
if (err)
|
||||
goto out;
|
||||
err = crypto_ahash_setkey(hmac_md5, cksumkey, kctx->gk5e->keylength);
|
||||
if (err)
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
|
|||
u64 seq_send;
|
||||
u8 *cksumkey;
|
||||
unsigned int cksum_usage;
|
||||
__be64 seq_send_be64;
|
||||
|
||||
dprintk("RPC: %s\n", __func__);
|
||||
|
||||
|
|
@ -187,7 +188,9 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
|
|||
spin_lock(&krb5_seq_lock);
|
||||
seq_send = ctx->seq_send64++;
|
||||
spin_unlock(&krb5_seq_lock);
|
||||
*((__be64 *)(krb5_hdr + 8)) = cpu_to_be64(seq_send);
|
||||
|
||||
seq_send_be64 = cpu_to_be64(seq_send);
|
||||
memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8);
|
||||
|
||||
if (ctx->initiate) {
|
||||
cksumkey = ctx->initiator_sign;
|
||||
|
|
|
|||
|
|
@ -155,10 +155,12 @@ gss_verify_mic_v2(struct krb5_ctx *ctx,
|
|||
u8 flags;
|
||||
int i;
|
||||
unsigned int cksum_usage;
|
||||
__be16 be16_ptr;
|
||||
|
||||
dprintk("RPC: %s\n", __func__);
|
||||
|
||||
if (be16_to_cpu(*((__be16 *)ptr)) != KG2_TOK_MIC)
|
||||
memcpy(&be16_ptr, (char *) ptr, 2);
|
||||
if (be16_to_cpu(be16_ptr) != KG2_TOK_MIC)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
flags = ptr[2];
|
||||
|
|
|
|||
|
|
@ -1450,8 +1450,8 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
|
|||
struct cache_detail *cd)
|
||||
{
|
||||
char tbuf[20];
|
||||
char *bp, *ep;
|
||||
time_t then, now;
|
||||
char *ep;
|
||||
time_t now;
|
||||
|
||||
if (*ppos || count > sizeof(tbuf)-1)
|
||||
return -EINVAL;
|
||||
|
|
@ -1461,24 +1461,24 @@ static ssize_t write_flush(struct file *file, const char __user *buf,
|
|||
simple_strtoul(tbuf, &ep, 0);
|
||||
if (*ep && *ep != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
bp = tbuf;
|
||||
then = get_expiry(&bp);
|
||||
now = seconds_since_boot();
|
||||
cd->nextcheck = now;
|
||||
/* Can only set flush_time to 1 second beyond "now", or
|
||||
* possibly 1 second beyond flushtime. This is because
|
||||
* flush_time never goes backwards so it mustn't get too far
|
||||
* ahead of time.
|
||||
/* Note that while we check that 'buf' holds a valid number,
|
||||
* we always ignore the value and just flush everything.
|
||||
* Making use of the number leads to races.
|
||||
*/
|
||||
if (then >= now) {
|
||||
/* Want to flush everything, so behave like cache_purge() */
|
||||
if (cd->flush_time >= now)
|
||||
now = cd->flush_time + 1;
|
||||
then = now;
|
||||
}
|
||||
|
||||
cd->flush_time = then;
|
||||
now = seconds_since_boot();
|
||||
/* Always flush everything, so behave like cache_purge()
|
||||
* Do this by advancing flush_time to the current time,
|
||||
* or by one second if it has already reached the current time.
|
||||
* Newly added cache entries will always have ->last_refresh greater
|
||||
* that ->flush_time, so they don't get flushed prematurely.
|
||||
*/
|
||||
|
||||
if (cd->flush_time >= now)
|
||||
now = cd->flush_time + 1;
|
||||
|
||||
cd->flush_time = now;
|
||||
cd->nextcheck = now;
|
||||
cache_flush();
|
||||
|
||||
*ppos += count;
|
||||
|
|
|
|||
118
net/sunrpc/svc.c
118
net/sunrpc/svc.c
|
|
@ -1255,6 +1255,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)
|
|||
|
||||
/* Syntactic check complete */
|
||||
serv->sv_stats->rpccnt++;
|
||||
trace_svc_process(rqstp, progp->pg_name);
|
||||
|
||||
/* Build the reply header. */
|
||||
statp = resv->iov_base +resv->iov_len;
|
||||
|
|
@ -1431,14 +1432,10 @@ svc_process(struct svc_rqst *rqstp)
|
|||
}
|
||||
|
||||
/* Returns 1 for send, 0 for drop */
|
||||
if (likely(svc_process_common(rqstp, argv, resv))) {
|
||||
int ret = svc_send(rqstp);
|
||||
if (likely(svc_process_common(rqstp, argv, resv)))
|
||||
return svc_send(rqstp);
|
||||
|
||||
trace_svc_process(rqstp, ret);
|
||||
return ret;
|
||||
}
|
||||
out_drop:
|
||||
trace_svc_process(rqstp, 0);
|
||||
svc_drop(rqstp);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1536,3 +1533,112 @@ u32 svc_max_payload(const struct svc_rqst *rqstp)
|
|||
return max;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_max_payload);
|
||||
|
||||
/**
|
||||
* svc_fill_write_vector - Construct data argument for VFS write call
|
||||
* @rqstp: svc_rqst to operate on
|
||||
* @first: buffer containing first section of write payload
|
||||
* @total: total number of bytes of write payload
|
||||
*
|
||||
* Returns the number of elements populated in the data argument array.
|
||||
*/
|
||||
unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct kvec *first,
|
||||
size_t total)
|
||||
{
|
||||
struct kvec *vec = rqstp->rq_vec;
|
||||
struct page **pages;
|
||||
unsigned int i;
|
||||
|
||||
/* Some types of transport can present the write payload
|
||||
* entirely in rq_arg.pages. In this case, @first is empty.
|
||||
*/
|
||||
i = 0;
|
||||
if (first->iov_len) {
|
||||
vec[i].iov_base = first->iov_base;
|
||||
vec[i].iov_len = min_t(size_t, total, first->iov_len);
|
||||
total -= vec[i].iov_len;
|
||||
++i;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(rqstp->rq_arg.page_base != 0);
|
||||
pages = rqstp->rq_arg.pages;
|
||||
while (total) {
|
||||
vec[i].iov_base = page_address(*pages);
|
||||
vec[i].iov_len = min_t(size_t, total, PAGE_SIZE);
|
||||
total -= vec[i].iov_len;
|
||||
++i;
|
||||
|
||||
++pages;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(i > ARRAY_SIZE(rqstp->rq_vec));
|
||||
return i;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_fill_write_vector);
|
||||
|
||||
/**
|
||||
* svc_fill_symlink_pathname - Construct pathname argument for VFS symlink call
|
||||
* @rqstp: svc_rqst to operate on
|
||||
* @first: buffer containing first section of pathname
|
||||
* @total: total length of the pathname argument
|
||||
*
|
||||
* Returns pointer to a NUL-terminated string, or an ERR_PTR. The buffer is
|
||||
* released automatically when @rqstp is recycled.
|
||||
*/
|
||||
char *svc_fill_symlink_pathname(struct svc_rqst *rqstp, struct kvec *first,
|
||||
size_t total)
|
||||
{
|
||||
struct xdr_buf *arg = &rqstp->rq_arg;
|
||||
struct page **pages;
|
||||
char *result;
|
||||
|
||||
/* VFS API demands a NUL-terminated pathname. This function
|
||||
* uses a page from @rqstp as the pathname buffer, to enable
|
||||
* direct placement. Thus the total buffer size is PAGE_SIZE.
|
||||
* Space in this buffer for NUL-termination requires that we
|
||||
* cap the size of the returned symlink pathname just a
|
||||
* little early.
|
||||
*/
|
||||
if (total > PAGE_SIZE - 1)
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
|
||||
/* Some types of transport can present the pathname entirely
|
||||
* in rq_arg.pages. If not, then copy the pathname into one
|
||||
* page.
|
||||
*/
|
||||
pages = arg->pages;
|
||||
WARN_ON_ONCE(arg->page_base != 0);
|
||||
if (first->iov_base == 0) {
|
||||
result = page_address(*pages);
|
||||
result[total] = '\0';
|
||||
} else {
|
||||
size_t len, remaining;
|
||||
char *dst;
|
||||
|
||||
result = page_address(*(rqstp->rq_next_page++));
|
||||
dst = result;
|
||||
remaining = total;
|
||||
|
||||
len = min_t(size_t, total, first->iov_len);
|
||||
memcpy(dst, first->iov_base, len);
|
||||
dst += len;
|
||||
remaining -= len;
|
||||
|
||||
/* No more than one page left */
|
||||
if (remaining) {
|
||||
len = min_t(size_t, remaining, PAGE_SIZE);
|
||||
memcpy(dst, page_address(*pages), len);
|
||||
dst += len;
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Sanity check: we don't allow the pathname argument to
|
||||
* contain a NUL byte.
|
||||
*/
|
||||
if (strlen(result) != total)
|
||||
return ERR_PTR(-EINVAL);
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_fill_symlink_pathname);
|
||||
|
|
|
|||
|
|
@ -173,6 +173,7 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
|
|||
set_bit(XPT_BUSY, &xprt->xpt_flags);
|
||||
rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
|
||||
xprt->xpt_net = get_net(net);
|
||||
strcpy(xprt->xpt_remotebuf, "uninitialized");
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_xprt_init);
|
||||
|
||||
|
|
@ -382,25 +383,21 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt)
|
|||
int cpu;
|
||||
|
||||
if (!svc_xprt_has_something_to_do(xprt))
|
||||
goto out;
|
||||
return;
|
||||
|
||||
/* Mark transport as busy. It will remain in this state until
|
||||
* the provider calls svc_xprt_received. We update XPT_BUSY
|
||||
* atomically because it also guards against trying to enqueue
|
||||
* the transport twice.
|
||||
*/
|
||||
if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) {
|
||||
/* Don't enqueue transport while already enqueued */
|
||||
dprintk("svc: transport %p busy, not enqueued\n", xprt);
|
||||
goto out;
|
||||
}
|
||||
if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags))
|
||||
return;
|
||||
|
||||
cpu = get_cpu();
|
||||
pool = svc_pool_for_cpu(xprt->xpt_server, cpu);
|
||||
|
||||
atomic_long_inc(&pool->sp_stats.packets);
|
||||
|
||||
dprintk("svc: transport %p put into queue\n", xprt);
|
||||
spin_lock_bh(&pool->sp_lock);
|
||||
list_add_tail(&xprt->xpt_ready, &pool->sp_sockets);
|
||||
pool->sp_stats.sockets_queued++;
|
||||
|
|
@ -412,6 +409,7 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt)
|
|||
if (test_and_set_bit(RQ_BUSY, &rqstp->rq_flags))
|
||||
continue;
|
||||
atomic_long_inc(&pool->sp_stats.threads_woken);
|
||||
rqstp->rq_qtime = ktime_get();
|
||||
wake_up_process(rqstp->rq_task);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
@ -420,7 +418,6 @@ void svc_xprt_do_enqueue(struct svc_xprt *xprt)
|
|||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
put_cpu();
|
||||
out:
|
||||
trace_svc_xprt_do_enqueue(xprt, rqstp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_xprt_do_enqueue);
|
||||
|
|
@ -454,13 +451,9 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool)
|
|||
struct svc_xprt, xpt_ready);
|
||||
list_del_init(&xprt->xpt_ready);
|
||||
svc_xprt_get(xprt);
|
||||
|
||||
dprintk("svc: transport %p dequeued, inuse=%d\n",
|
||||
xprt, kref_read(&xprt->xpt_ref));
|
||||
}
|
||||
spin_unlock_bh(&pool->sp_lock);
|
||||
out:
|
||||
trace_svc_xprt_dequeue(xprt);
|
||||
return xprt;
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +485,7 @@ static void svc_xprt_release(struct svc_rqst *rqstp)
|
|||
{
|
||||
struct svc_xprt *xprt = rqstp->rq_xprt;
|
||||
|
||||
rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
|
||||
xprt->xpt_ops->xpo_release_rqst(rqstp);
|
||||
|
||||
kfree(rqstp->rq_deferred);
|
||||
rqstp->rq_deferred = NULL;
|
||||
|
|
@ -538,7 +531,6 @@ void svc_wake_up(struct svc_serv *serv)
|
|||
if (test_bit(RQ_BUSY, &rqstp->rq_flags))
|
||||
continue;
|
||||
rcu_read_unlock();
|
||||
dprintk("svc: daemon %p woken up.\n", rqstp);
|
||||
wake_up_process(rqstp->rq_task);
|
||||
trace_svc_wake_up(rqstp->rq_task->pid);
|
||||
return;
|
||||
|
|
@ -734,6 +726,7 @@ out_found:
|
|||
rqstp->rq_chandle.thread_wait = 5*HZ;
|
||||
else
|
||||
rqstp->rq_chandle.thread_wait = 1*HZ;
|
||||
trace_svc_xprt_dequeue(rqstp);
|
||||
return rqstp->rq_xprt;
|
||||
}
|
||||
|
||||
|
|
@ -789,7 +782,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt)
|
|||
len = svc_deferred_recv(rqstp);
|
||||
else
|
||||
len = xprt->xpt_ops->xpo_recvfrom(rqstp);
|
||||
dprintk("svc: got len=%d\n", len);
|
||||
rqstp->rq_stime = ktime_get();
|
||||
rqstp->rq_reserved = serv->sv_max_mesg;
|
||||
atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved);
|
||||
}
|
||||
|
|
@ -844,10 +837,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout)
|
|||
|
||||
clear_bit(XPT_OLD, &xprt->xpt_flags);
|
||||
|
||||
if (xprt->xpt_ops->xpo_secure_port(rqstp))
|
||||
set_bit(RQ_SECURE, &rqstp->rq_flags);
|
||||
else
|
||||
clear_bit(RQ_SECURE, &rqstp->rq_flags);
|
||||
xprt->xpt_ops->xpo_secure_port(rqstp);
|
||||
rqstp->rq_chandle.defer = svc_defer;
|
||||
rqstp->rq_xid = svc_getu32(&rqstp->rq_arg.head[0]);
|
||||
|
||||
|
|
@ -859,7 +849,6 @@ out_release:
|
|||
rqstp->rq_res.len = 0;
|
||||
svc_xprt_release(rqstp);
|
||||
out:
|
||||
trace_svc_recv(rqstp, err);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_recv);
|
||||
|
|
@ -889,7 +878,7 @@ int svc_send(struct svc_rqst *rqstp)
|
|||
goto out;
|
||||
|
||||
/* release the receive skb before sending the reply */
|
||||
rqstp->rq_xprt->xpt_ops->xpo_release_rqst(rqstp);
|
||||
xprt->xpt_ops->xpo_release_rqst(rqstp);
|
||||
|
||||
/* calculate over-all length */
|
||||
xb = &rqstp->rq_res;
|
||||
|
|
@ -899,6 +888,7 @@ int svc_send(struct svc_rqst *rqstp)
|
|||
|
||||
/* Grab mutex to serialize outgoing data. */
|
||||
mutex_lock(&xprt->xpt_mutex);
|
||||
trace_svc_stats_latency(rqstp);
|
||||
if (test_bit(XPT_DEAD, &xprt->xpt_flags)
|
||||
|| test_bit(XPT_CLOSE, &xprt->xpt_flags))
|
||||
len = -ENOTCONN;
|
||||
|
|
@ -906,12 +896,12 @@ int svc_send(struct svc_rqst *rqstp)
|
|||
len = xprt->xpt_ops->xpo_sendto(rqstp);
|
||||
mutex_unlock(&xprt->xpt_mutex);
|
||||
rpc_wake_up(&xprt->xpt_bc_pending);
|
||||
trace_svc_send(rqstp, len);
|
||||
svc_xprt_release(rqstp);
|
||||
|
||||
if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
|
||||
len = 0;
|
||||
out:
|
||||
trace_svc_send(rqstp, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -391,9 +391,12 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd,
|
|||
release_sock(sock->sk);
|
||||
}
|
||||
|
||||
static int svc_sock_secure_port(struct svc_rqst *rqstp)
|
||||
static void svc_sock_secure_port(struct svc_rqst *rqstp)
|
||||
{
|
||||
return svc_port_is_privileged(svc_addr(rqstp));
|
||||
if (svc_port_is_privileged(svc_addr(rqstp)))
|
||||
set_bit(RQ_SECURE, &rqstp->rq_flags);
|
||||
else
|
||||
clear_bit(RQ_SECURE, &rqstp->rq_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1309,6 +1312,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
|
|||
set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
|
||||
if (sk->sk_state == TCP_LISTEN) {
|
||||
dprintk("setting up TCP socket for listening\n");
|
||||
strcpy(svsk->sk_xprt.xpt_remotebuf, "listener");
|
||||
set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags);
|
||||
sk->sk_data_ready = svc_tcp_listen_data_ready;
|
||||
set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
|
||||
|
|
|
|||
|
|
@ -51,9 +51,9 @@
|
|||
#define RPCDBG_FACILITY RPCDBG_SVCXPRT
|
||||
|
||||
/* RPC/RDMA parameters */
|
||||
unsigned int svcrdma_ord = RPCRDMA_ORD;
|
||||
unsigned int svcrdma_ord = 16; /* historical default */
|
||||
static unsigned int min_ord = 1;
|
||||
static unsigned int max_ord = 4096;
|
||||
static unsigned int max_ord = 255;
|
||||
unsigned int svcrdma_max_requests = RPCRDMA_MAX_REQUESTS;
|
||||
unsigned int svcrdma_max_bc_requests = RPCRDMA_MAX_BC_REQUESTS;
|
||||
static unsigned int min_max_requests = 4;
|
||||
|
|
|
|||
|
|
@ -110,15 +110,16 @@
|
|||
* the RDMA_RECV completion. The SGL should contain full pages up until the
|
||||
* last one.
|
||||
*/
|
||||
static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
|
||||
struct svc_rdma_op_ctxt *ctxt,
|
||||
u32 byte_count)
|
||||
static void svc_rdma_build_arg_xdr(struct svc_rqst *rqstp,
|
||||
struct svc_rdma_op_ctxt *ctxt)
|
||||
{
|
||||
struct page *page;
|
||||
u32 bc;
|
||||
int sge_no;
|
||||
u32 len;
|
||||
|
||||
/* Swap the page in the SGE with the page in argpages */
|
||||
/* The reply path assumes the Call's transport header resides
|
||||
* in rqstp->rq_pages[0].
|
||||
*/
|
||||
page = ctxt->pages[0];
|
||||
put_page(rqstp->rq_pages[0]);
|
||||
rqstp->rq_pages[0] = page;
|
||||
|
|
@ -126,35 +127,35 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
|
|||
/* Set up the XDR head */
|
||||
rqstp->rq_arg.head[0].iov_base = page_address(page);
|
||||
rqstp->rq_arg.head[0].iov_len =
|
||||
min_t(size_t, byte_count, ctxt->sge[0].length);
|
||||
rqstp->rq_arg.len = byte_count;
|
||||
rqstp->rq_arg.buflen = byte_count;
|
||||
min_t(size_t, ctxt->byte_len, ctxt->sge[0].length);
|
||||
rqstp->rq_arg.len = ctxt->byte_len;
|
||||
rqstp->rq_arg.buflen = ctxt->byte_len;
|
||||
|
||||
/* Compute bytes past head in the SGL */
|
||||
bc = byte_count - rqstp->rq_arg.head[0].iov_len;
|
||||
len = ctxt->byte_len - rqstp->rq_arg.head[0].iov_len;
|
||||
|
||||
/* If data remains, store it in the pagelist */
|
||||
rqstp->rq_arg.page_len = bc;
|
||||
rqstp->rq_arg.page_len = len;
|
||||
rqstp->rq_arg.page_base = 0;
|
||||
|
||||
sge_no = 1;
|
||||
while (bc && sge_no < ctxt->count) {
|
||||
while (len && sge_no < ctxt->count) {
|
||||
page = ctxt->pages[sge_no];
|
||||
put_page(rqstp->rq_pages[sge_no]);
|
||||
rqstp->rq_pages[sge_no] = page;
|
||||
bc -= min_t(u32, bc, ctxt->sge[sge_no].length);
|
||||
len -= min_t(u32, len, ctxt->sge[sge_no].length);
|
||||
sge_no++;
|
||||
}
|
||||
rqstp->rq_respages = &rqstp->rq_pages[sge_no];
|
||||
rqstp->rq_next_page = rqstp->rq_respages + 1;
|
||||
|
||||
/* If not all pages were used from the SGL, free the remaining ones */
|
||||
bc = sge_no;
|
||||
len = sge_no;
|
||||
while (sge_no < ctxt->count) {
|
||||
page = ctxt->pages[sge_no++];
|
||||
put_page(page);
|
||||
}
|
||||
ctxt->count = bc;
|
||||
ctxt->count = len;
|
||||
|
||||
/* Set up tail */
|
||||
rqstp->rq_arg.tail[0].iov_base = NULL;
|
||||
|
|
@ -534,10 +535,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
|
|||
ctxt, rdma_xprt, rqstp);
|
||||
atomic_inc(&rdma_stat_recv);
|
||||
|
||||
/* Build up the XDR from the receive buffers. */
|
||||
rdma_build_arg_xdr(rqstp, ctxt, ctxt->byte_len);
|
||||
svc_rdma_build_arg_xdr(rqstp, ctxt);
|
||||
|
||||
/* Decode the RDMA header. */
|
||||
p = (__be32 *)rqstp->rq_arg.head[0].iov_base;
|
||||
ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg);
|
||||
if (ret < 0)
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ static void svc_rdma_release_rqst(struct svc_rqst *);
|
|||
static void svc_rdma_detach(struct svc_xprt *xprt);
|
||||
static void svc_rdma_free(struct svc_xprt *xprt);
|
||||
static int svc_rdma_has_wspace(struct svc_xprt *xprt);
|
||||
static int svc_rdma_secure_port(struct svc_rqst *);
|
||||
static void svc_rdma_secure_port(struct svc_rqst *);
|
||||
static void svc_rdma_kill_temp_xprt(struct svc_xprt *);
|
||||
|
||||
static const struct svc_xprt_ops svc_rdma_ops = {
|
||||
|
|
@ -330,9 +330,9 @@ static void svc_rdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
|
|||
|
||||
flushed:
|
||||
if (wc->status != IB_WC_WR_FLUSH_ERR)
|
||||
pr_warn("svcrdma: receive: %s (%u/0x%x)\n",
|
||||
ib_wc_status_msg(wc->status),
|
||||
wc->status, wc->vendor_err);
|
||||
pr_err("svcrdma: Recv: %s (%u/0x%x)\n",
|
||||
ib_wc_status_msg(wc->status),
|
||||
wc->status, wc->vendor_err);
|
||||
set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
|
||||
svc_rdma_put_context(ctxt, 1);
|
||||
|
||||
|
|
@ -401,8 +401,10 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
|
|||
*/
|
||||
set_bit(XPT_CONG_CTRL, &cma_xprt->sc_xprt.xpt_flags);
|
||||
|
||||
if (listener)
|
||||
if (listener) {
|
||||
strcpy(cma_xprt->sc_xprt.xpt_remotebuf, "listener");
|
||||
set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags);
|
||||
}
|
||||
|
||||
return cma_xprt;
|
||||
}
|
||||
|
|
@ -762,13 +764,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
|
|||
if (!svc_rdma_prealloc_ctxts(newxprt))
|
||||
goto errout;
|
||||
|
||||
/*
|
||||
* Limit ORD based on client limit, local device limit, and
|
||||
* configured svcrdma limit.
|
||||
*/
|
||||
newxprt->sc_ord = min_t(size_t, dev->attrs.max_qp_rd_atom, newxprt->sc_ord);
|
||||
newxprt->sc_ord = min_t(size_t, svcrdma_ord, newxprt->sc_ord);
|
||||
|
||||
newxprt->sc_pd = ib_alloc_pd(dev, 0);
|
||||
if (IS_ERR(newxprt->sc_pd)) {
|
||||
dprintk("svcrdma: error creating PD for connect request\n");
|
||||
|
|
@ -843,15 +838,18 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
|
|||
set_bit(RDMAXPRT_CONN_PENDING, &newxprt->sc_flags);
|
||||
memset(&conn_param, 0, sizeof conn_param);
|
||||
conn_param.responder_resources = 0;
|
||||
conn_param.initiator_depth = newxprt->sc_ord;
|
||||
conn_param.initiator_depth = min_t(int, newxprt->sc_ord,
|
||||
dev->attrs.max_qp_init_rd_atom);
|
||||
if (!conn_param.initiator_depth) {
|
||||
dprintk("svcrdma: invalid ORD setting\n");
|
||||
ret = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
conn_param.private_data = &pmsg;
|
||||
conn_param.private_data_len = sizeof(pmsg);
|
||||
ret = rdma_accept(newxprt->sc_cm_id, &conn_param);
|
||||
if (ret) {
|
||||
dprintk("svcrdma: failed to accept new connection, ret=%d\n",
|
||||
ret);
|
||||
if (ret)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
dprintk("svcrdma: new connection %p accepted:\n", newxprt);
|
||||
sap = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.src_addr;
|
||||
|
|
@ -862,7 +860,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
|
|||
dprintk(" sq_depth : %d\n", newxprt->sc_sq_depth);
|
||||
dprintk(" rdma_rw_ctxs : %d\n", ctxts);
|
||||
dprintk(" max_requests : %d\n", newxprt->sc_max_requests);
|
||||
dprintk(" ord : %d\n", newxprt->sc_ord);
|
||||
dprintk(" ord : %d\n", conn_param.initiator_depth);
|
||||
|
||||
return &newxprt->sc_xprt;
|
||||
|
||||
|
|
@ -992,9 +990,9 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int svc_rdma_secure_port(struct svc_rqst *rqstp)
|
||||
static void svc_rdma_secure_port(struct svc_rqst *rqstp)
|
||||
{
|
||||
return 1;
|
||||
set_bit(RQ_SECURE, &rqstp->rq_flags);
|
||||
}
|
||||
|
||||
static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)
|
||||
|
|
|
|||
Loading…
Reference in a new issue