Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
68432a03
Commit
68432a03
authored
May 20, 2008
by
J. Bruce Fields
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'from-tomtucker' into for-2.6.26
parents
d71a4dd7
a6f911c0
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
223 additions
and
215 deletions
+223
-215
include/linux/sunrpc/svc_rdma.h
include/linux/sunrpc/svc_rdma.h
+7
-5
net/sunrpc/svc_xprt.c
net/sunrpc/svc_xprt.c
+0
-23
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+31
-71
net/sunrpc/xprtrdma/svc_rdma_sendto.c
net/sunrpc/xprtrdma/svc_rdma_sendto.c
+11
-0
net/sunrpc/xprtrdma/svc_rdma_transport.c
net/sunrpc/xprtrdma/svc_rdma_transport.c
+174
-116
No files found.
include/linux/sunrpc/svc_rdma.h
View file @
68432a03
...
...
@@ -71,7 +71,8 @@ extern atomic_t rdma_stat_sq_prod;
* completes.
*/
struct
svc_rdma_op_ctxt
{
struct
svc_rdma_op_ctxt
*
next
;
struct
svc_rdma_op_ctxt
*
read_hdr
;
struct
list_head
free_list
;
struct
xdr_buf
arg
;
struct
list_head
dto_q
;
enum
ib_wr_opcode
wr_op
;
...
...
@@ -85,7 +86,6 @@ struct svc_rdma_op_ctxt {
struct
page
*
pages
[
RPCSVC_MAXPAGES
];
};
#define RDMACTXT_F_READ_DONE 1
#define RDMACTXT_F_LAST_CTXT 2
struct
svcxprt_rdma
{
...
...
@@ -104,7 +104,8 @@ struct svcxprt_rdma {
struct
ib_pd
*
sc_pd
;
struct
svc_rdma_op_ctxt
*
sc_ctxt_head
;
atomic_t
sc_ctxt_used
;
struct
list_head
sc_ctxt_free
;
int
sc_ctxt_cnt
;
int
sc_ctxt_bump
;
int
sc_ctxt_max
;
...
...
@@ -123,6 +124,7 @@ struct svcxprt_rdma {
struct
list_head
sc_dto_q
;
/* DTO tasklet I/O pending Q */
struct
list_head
sc_read_complete_q
;
spinlock_t
sc_read_complete_lock
;
struct
work_struct
sc_work
;
};
/* sc_flags */
#define RDMAXPRT_RQ_PENDING 1
...
...
@@ -164,7 +166,7 @@ extern int svc_rdma_sendto(struct svc_rqst *);
/* svc_rdma_transport.c */
extern
int
svc_rdma_send
(
struct
svcxprt_rdma
*
,
struct
ib_send_wr
*
);
extern
int
svc_rdma_send_error
(
struct
svcxprt_rdma
*
,
struct
rpcrdma_msg
*
,
extern
void
svc_rdma_send_error
(
struct
svcxprt_rdma
*
,
struct
rpcrdma_msg
*
,
enum
rpcrdma_errcode
);
struct
page
*
svc_rdma_get_page
(
void
);
extern
int
svc_rdma_post_recv
(
struct
svcxprt_rdma
*
);
...
...
net/sunrpc/svc_xprt.c
View file @
68432a03
...
...
@@ -6,30 +6,9 @@
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/file.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <net/sock.h>
#include <net/checksum.h>
#include <net/ip.h>
#include <net/ipv6.h>
#include <net/tcp_states.h>
#include <linux/uaccess.h>
#include <asm/ioctls.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/svc_xprt.h>
...
...
@@ -296,8 +275,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt)
if
(
!
(
xprt
->
xpt_flags
&
((
1
<<
XPT_CONN
)
|
(
1
<<
XPT_DATA
)
|
(
1
<<
XPT_CLOSE
)
|
(
1
<<
XPT_DEFERRED
))))
return
;
if
(
test_bit
(
XPT_DEAD
,
&
xprt
->
xpt_flags
))
return
;
cpu
=
get_cpu
();
pool
=
svc_pool_for_cpu
(
xprt
->
xpt_server
,
cpu
);
...
...
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
View file @
68432a03
...
...
@@ -260,11 +260,16 @@ static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count)
* On our side, we need to read into a pagelist. The first page immediately
* follows the RPC header.
*
* This function returns 1 to indicate success. The data is not yet in
* This function returns:
* 0 - No error and no read-list found.
*
* 1 - Successful read-list processing. The data is not yet in
* the pagelist and therefore the RPC request must be deferred. The
* I/O completion will enqueue the transport again and
* svc_rdma_recvfrom will complete the request.
*
* <0 - Error processing/posting read-list.
*
* NOTE: The ctxt must not be touched after the last WR has been posted
* because the I/O completion processing may occur on another
* processor and free / modify the context. Ne touche pas!
...
...
@@ -284,7 +289,6 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
u64
sgl_offset
;
struct
rpcrdma_read_chunk
*
ch
;
struct
svc_rdma_op_ctxt
*
ctxt
=
NULL
;
struct
svc_rdma_op_ctxt
*
head
;
struct
svc_rdma_op_ctxt
*
tmp_sge_ctxt
;
struct
svc_rdma_op_ctxt
*
tmp_ch_ctxt
;
struct
chunk_sge
*
ch_sge_ary
;
...
...
@@ -302,25 +306,19 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
ch_sge_ary
=
(
struct
chunk_sge
*
)
tmp_ch_ctxt
->
sge
;
svc_rdma_rcl_chunk_counts
(
ch
,
&
ch_count
,
&
byte_count
);
if
(
ch_count
>
RPCSVC_MAXPAGES
)
return
-
EINVAL
;
sge_count
=
rdma_rcl_to_sge
(
xprt
,
rqstp
,
hdr_ctxt
,
rmsgp
,
sge
,
ch_sge_ary
,
ch_count
,
byte_count
);
head
=
svc_rdma_get_context
(
xprt
);
sgl_offset
=
0
;
ch_no
=
0
;
for
(
ch
=
(
struct
rpcrdma_read_chunk
*
)
&
rmsgp
->
rm_body
.
rm_chunks
[
0
];
ch
->
rc_discrim
!=
0
;
ch
++
,
ch_no
++
)
{
next_sge:
if
(
!
ctxt
)
ctxt
=
head
;
else
{
ctxt
->
next
=
svc_rdma_get_context
(
xprt
);
ctxt
=
ctxt
->
next
;
}
ctxt
->
next
=
NULL
;
ctxt
=
svc_rdma_get_context
(
xprt
);
ctxt
->
direction
=
DMA_FROM_DEVICE
;
clear_bit
(
RDMACTXT_F_READ_DONE
,
&
ctxt
->
flags
);
clear_bit
(
RDMACTXT_F_LAST_CTXT
,
&
ctxt
->
flags
);
/* Prepare READ WR */
...
...
@@ -347,20 +345,15 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
* the client and the RPC needs to be enqueued.
*/
set_bit
(
RDMACTXT_F_LAST_CTXT
,
&
ctxt
->
flags
);
ctxt
->
next
=
hdr_ctxt
;
hdr_ctxt
->
next
=
head
;
ctxt
->
read_hdr
=
hdr_ctxt
;
}
/* Post the read */
err
=
svc_rdma_send
(
xprt
,
&
read_wr
);
if
(
err
)
{
printk
(
KERN_ERR
"svcrdma: Error
posting send = %d
\n
"
,
printk
(
KERN_ERR
"svcrdma: Error
%d posting RDMA_READ
\n
"
,
err
);
/*
* Break the circular list so free knows when
* to stop if the error happened to occur on
* the last read
*/
ctxt
->
next
=
NULL
;
set_bit
(
XPT_CLOSE
,
&
xprt
->
sc_xprt
.
xpt_flags
);
svc_rdma_put_context
(
ctxt
,
0
);
goto
out
;
}
atomic_inc
(
&
rdma_stat_read
);
...
...
@@ -371,7 +364,7 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
goto
next_sge
;
}
sgl_offset
=
0
;
err
=
0
;
err
=
1
;
}
out:
...
...
@@ -389,25 +382,12 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
while
(
rqstp
->
rq_resused
)
rqstp
->
rq_respages
[
--
rqstp
->
rq_resused
]
=
NULL
;
if
(
err
)
{
printk
(
KERN_ERR
"svcrdma : RDMA_READ error = %d
\n
"
,
err
);
set_bit
(
XPT_CLOSE
,
&
xprt
->
sc_xprt
.
xpt_flags
);
/* Free the linked list of read contexts */
while
(
head
!=
NULL
)
{
ctxt
=
head
->
next
;
svc_rdma_put_context
(
head
,
1
);
head
=
ctxt
;
}
return
0
;
}
return
1
;
return
err
;
}
static
int
rdma_read_complete
(
struct
svc_rqst
*
rqstp
,
struct
svc_rdma_op_ctxt
*
data
)
struct
svc_rdma_op_ctxt
*
head
)
{
struct
svc_rdma_op_ctxt
*
head
=
data
->
next
;
int
page_no
;
int
ret
;
...
...
@@ -433,21 +413,12 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
rqstp
->
rq_arg
.
len
=
head
->
arg
.
len
;
rqstp
->
rq_arg
.
buflen
=
head
->
arg
.
buflen
;
/* Free the context */
svc_rdma_put_context
(
head
,
0
);
/* XXX: What should this be? */
rqstp
->
rq_prot
=
IPPROTO_MAX
;
/*
* Free the contexts we used to build the RDMA_READ. We have
* to be careful here because the context list uses the same
* next pointer used to chain the contexts associated with the
* RDMA_READ
*/
data
->
next
=
NULL
;
/* terminate circular list */
do
{
data
=
head
->
next
;
svc_rdma_put_context
(
head
,
0
);
head
=
data
;
}
while
(
head
!=
NULL
);
svc_xprt_copy_addrs
(
rqstp
,
rqstp
->
rq_xprt
);
ret
=
rqstp
->
rq_arg
.
head
[
0
].
iov_len
+
rqstp
->
rq_arg
.
page_len
...
...
@@ -457,8 +428,6 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
ret
,
rqstp
->
rq_arg
.
len
,
rqstp
->
rq_arg
.
head
[
0
].
iov_base
,
rqstp
->
rq_arg
.
head
[
0
].
iov_len
);
/* Indicate that we've consumed an RQ credit */
rqstp
->
rq_xprt_ctxt
=
rqstp
->
rq_xprt
;
svc_xprt_received
(
rqstp
->
rq_xprt
);
return
ret
;
}
...
...
@@ -480,13 +449,6 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
dprintk
(
"svcrdma: rqstp=%p
\n
"
,
rqstp
);
/*
* The rq_xprt_ctxt indicates if we've consumed an RQ credit
* or not. It is used in the rdma xpo_release_rqst function to
* determine whether or not to return an RQ WQE to the RQ.
*/
rqstp
->
rq_xprt_ctxt
=
NULL
;
spin_lock_bh
(
&
rdma_xprt
->
sc_read_complete_lock
);
if
(
!
list_empty
(
&
rdma_xprt
->
sc_read_complete_q
))
{
ctxt
=
list_entry
(
rdma_xprt
->
sc_read_complete_q
.
next
,
...
...
@@ -537,21 +499,22 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
/* If the request is invalid, reply with an error */
if
(
len
<
0
)
{
if
(
len
==
-
ENOSYS
)
(
void
)
svc_rdma_send_error
(
rdma_xprt
,
rmsgp
,
ERR_VERS
);
svc_rdma_send_error
(
rdma_xprt
,
rmsgp
,
ERR_VERS
);
goto
close_out
;
}
/* Read read-list data. If we would need to wait, defer
* it. Not that in this case, we don't return the RQ credit
* until after the read completes.
*/
if
(
rdma_read_xdr
(
rdma_xprt
,
rmsgp
,
rqstp
,
ctxt
))
{
/* Read read-list data. */
ret
=
rdma_read_xdr
(
rdma_xprt
,
rmsgp
,
rqstp
,
ctxt
);
if
(
ret
>
0
)
{
/* read-list posted, defer until data received from client. */
svc_xprt_received
(
xprt
);
return
0
;
}
/* Indicate we've consumed an RQ credit */
rqstp
->
rq_xprt_ctxt
=
rqstp
->
rq_xprt
;
if
(
ret
<
0
)
{
/* Post of read-list failed, free context. */
svc_rdma_put_context
(
ctxt
,
1
);
return
0
;
}
ret
=
rqstp
->
rq_arg
.
head
[
0
].
iov_len
+
rqstp
->
rq_arg
.
page_len
...
...
@@ -569,11 +532,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
return
ret
;
close_out:
if
(
ctxt
)
{
if
(
ctxt
)
svc_rdma_put_context
(
ctxt
,
1
);
/* Indicate we've consumed an RQ credit */
rqstp
->
rq_xprt_ctxt
=
rqstp
->
rq_xprt
;
}
dprintk
(
"svcrdma: transport %p is closing
\n
"
,
xprt
);
/*
* Set the close bit and enqueue it. svc_recv will see the
...
...
net/sunrpc/xprtrdma/svc_rdma_sendto.c
View file @
68432a03
...
...
@@ -389,6 +389,17 @@ static int send_reply(struct svcxprt_rdma *rdma,
int
page_no
;
int
ret
;
/* Post a recv buffer to handle another request. */
ret
=
svc_rdma_post_recv
(
rdma
);
if
(
ret
)
{
printk
(
KERN_INFO
"svcrdma: could not post a receive buffer, err=%d."
"Closing transport %p.
\n
"
,
ret
,
rdma
);
set_bit
(
XPT_CLOSE
,
&
rdma
->
sc_xprt
.
xpt_flags
);
svc_rdma_put_context
(
ctxt
,
0
);
return
-
ENOTCONN
;
}
/* Prepare the context */
ctxt
->
pages
[
0
]
=
page
;
ctxt
->
count
=
1
;
...
...
net/sunrpc/xprtrdma/svc_rdma_transport.c
View file @
68432a03
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment