mirror of https://gitee.com/openkylin/linux.git
NFS Client Bugfixes for Linux 5.5-rc7
xprtrdma bugfixes: - Fix create_qp crash on device unload - Fix completion wait during device removal - Fix oops in receive handler after device removal -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEnZ5MQTpR7cLU7KEp18tUv7ClQOsFAl4eJKUACgkQ18tUv7Cl QOuZsRAAxmW8hxaAFySFxiRI1o2u0heahZfWY0F0hsMTCk1YpAXUf70+cBh+5Poe V6/5bCmHKdFYSstwuJOxLvhsCMxfAUc5JJMrBCawWOKbuo3tWj9yUmBoBicj3s9w 1uomBDOl+o1G3SVJ44on0QU+b84HAcvEyCMuNYGCCrItud2vogEZcnsr1emgBHSL hvv1RRQWVT8wJEj68mf2sN0B1SvGDzTEtyJj4iXTq502L3e4WfeMDNxJx9c7tiqE auZR0jrms5pLlMFtXqYjkCYuMSPzdtWFu36SLLMAELbMKSOxnJ+y42uNOSBMBTf1 SL6aXJloMI/vWqjyQhg63s9tW3SULTLd4wKW4JthJnAaQ0P3afMtxCrMv8bHOOnf 0EHHyl0lMT18UtVz1GLO+21MlY3iGeA9qV2uJrf4KnPig/OYhu6Y02MQoseN4fSI u1DMDkZKLIHgse1Yb9H57GhjA9EIMF6kaSi5BC+pSMssQ+hBxYeIPSj/RRBn9q2Z XVjXw1EWVEkBuUe245Uo5wkZnufIWIeM6rVCKf15+bS3UD/bv6nWXXR+XA3yXd68 MeoTIyRf0uhYIeaB3fFRhZaDtU2Uxitm4LXhdPOvdNEqm/A1uvYm2E6G/jdnA+Bk DDVabgP7DSQ13eXcfvEmwp3xzXesU3EUUK98++f82E30LMCGzIs= =Hw2/ -----END PGP SIGNATURE----- Merge tag 'nfs-for-5.5-2' of git://git.linux-nfs.org/projects/anna/linux-nfs Pull NFS client bugfixes from Anna Schumaker: "Three NFS over RDMA fixes for bugs Chuck found that can be hit during device removal: - Fix create_qp crash on device unload - Fix completion wait during device removal - Fix oops in receive handler after device removal" * tag 'nfs-for-5.5-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: xprtrdma: Fix oops in Receive handler after device removal xprtrdma: Fix completion wait during device removal xprtrdma: Fix create_qp crash on device unload
This commit is contained in:
commit
95e20af9fb
|
@ -77,7 +77,7 @@
|
|||
static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
|
||||
struct rpcrdma_sendctx *sc);
|
||||
static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
|
||||
static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf);
|
||||
static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt);
|
||||
static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
|
||||
static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt);
|
||||
static struct rpcrdma_regbuf *
|
||||
|
@ -244,6 +244,7 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
|
|||
ia->ri_id->device->name,
|
||||
rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt));
|
||||
#endif
|
||||
init_completion(&ia->ri_remove_done);
|
||||
set_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags);
|
||||
ep->rep_connected = -ENODEV;
|
||||
xprt_force_disconnect(xprt);
|
||||
|
@ -297,7 +298,6 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
|
|||
int rc;
|
||||
|
||||
init_completion(&ia->ri_done);
|
||||
init_completion(&ia->ri_remove_done);
|
||||
|
||||
id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_cm_event_handler,
|
||||
xprt, RDMA_PS_TCP, IB_QPT_RC);
|
||||
|
@ -421,7 +421,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
|
|||
/* The ULP is responsible for ensuring all DMA
|
||||
* mappings and MRs are gone.
|
||||
*/
|
||||
rpcrdma_reps_destroy(buf);
|
||||
rpcrdma_reps_unmap(r_xprt);
|
||||
list_for_each_entry(req, &buf->rb_allreqs, rl_all) {
|
||||
rpcrdma_regbuf_dma_unmap(req->rl_rdmabuf);
|
||||
rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);
|
||||
|
@ -599,6 +599,7 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt,
|
|||
struct ib_qp_init_attr *qp_init_attr)
|
||||
{
|
||||
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
|
||||
struct rpcrdma_ep *ep = &r_xprt->rx_ep;
|
||||
int rc, err;
|
||||
|
||||
trace_xprtrdma_reinsert(r_xprt);
|
||||
|
@ -613,6 +614,7 @@ static int rpcrdma_ep_recreate_xprt(struct rpcrdma_xprt *r_xprt,
|
|||
pr_err("rpcrdma: rpcrdma_ep_create returned %d\n", err);
|
||||
goto out2;
|
||||
}
|
||||
memcpy(qp_init_attr, &ep->rep_attr, sizeof(*qp_init_attr));
|
||||
|
||||
rc = -ENETUNREACH;
|
||||
err = rdma_create_qp(ia->ri_id, ia->ri_pd, qp_init_attr);
|
||||
|
@ -1090,6 +1092,7 @@ static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
|
|||
rep->rr_recv_wr.sg_list = &rep->rr_rdmabuf->rg_iov;
|
||||
rep->rr_recv_wr.num_sge = 1;
|
||||
rep->rr_temp = temp;
|
||||
list_add(&rep->rr_all, &r_xprt->rx_buf.rb_all_reps);
|
||||
return rep;
|
||||
|
||||
out_free:
|
||||
|
@ -1100,6 +1103,7 @@ static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
|
|||
|
||||
static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep)
|
||||
{
|
||||
list_del(&rep->rr_all);
|
||||
rpcrdma_regbuf_free(rep->rr_rdmabuf);
|
||||
kfree(rep);
|
||||
}
|
||||
|
@ -1118,10 +1122,16 @@ static struct rpcrdma_rep *rpcrdma_rep_get_locked(struct rpcrdma_buffer *buf)
|
|||
static void rpcrdma_rep_put(struct rpcrdma_buffer *buf,
|
||||
struct rpcrdma_rep *rep)
|
||||
{
|
||||
if (!rep->rr_temp)
|
||||
llist_add(&rep->rr_node, &buf->rb_free_reps);
|
||||
else
|
||||
rpcrdma_rep_destroy(rep);
|
||||
llist_add(&rep->rr_node, &buf->rb_free_reps);
|
||||
}
|
||||
|
||||
static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt)
|
||||
{
|
||||
struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
|
||||
struct rpcrdma_rep *rep;
|
||||
|
||||
list_for_each_entry(rep, &buf->rb_all_reps, rr_all)
|
||||
rpcrdma_regbuf_dma_unmap(rep->rr_rdmabuf);
|
||||
}
|
||||
|
||||
static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf)
|
||||
|
@ -1152,6 +1162,7 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
|
|||
|
||||
INIT_LIST_HEAD(&buf->rb_send_bufs);
|
||||
INIT_LIST_HEAD(&buf->rb_allreqs);
|
||||
INIT_LIST_HEAD(&buf->rb_all_reps);
|
||||
|
||||
rc = -ENOMEM;
|
||||
for (i = 0; i < buf->rb_max_requests; i++) {
|
||||
|
@ -1504,6 +1515,10 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
|
|||
wr = NULL;
|
||||
while (needed) {
|
||||
rep = rpcrdma_rep_get_locked(buf);
|
||||
if (rep && rep->rr_temp) {
|
||||
rpcrdma_rep_destroy(rep);
|
||||
continue;
|
||||
}
|
||||
if (!rep)
|
||||
rep = rpcrdma_rep_create(r_xprt, temp);
|
||||
if (!rep)
|
||||
|
|
|
@ -203,6 +203,7 @@ struct rpcrdma_rep {
|
|||
struct xdr_stream rr_stream;
|
||||
struct llist_node rr_node;
|
||||
struct ib_recv_wr rr_recv_wr;
|
||||
struct list_head rr_all;
|
||||
};
|
||||
|
||||
/* To reduce the rate at which a transport invokes ib_post_recv
|
||||
|
@ -368,6 +369,7 @@ struct rpcrdma_buffer {
|
|||
|
||||
struct list_head rb_allreqs;
|
||||
struct list_head rb_all_mrs;
|
||||
struct list_head rb_all_reps;
|
||||
|
||||
struct llist_head rb_free_reps;
|
||||
|
||||
|
|
Loading…
Reference in New Issue