From 2b6e72ed747f68a038df616efd86744b3644d694 Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Fri, 17 Jan 2014 18:31:00 +0100 Subject: 9P: Add memory barriers to protect request fields over cb/rpc threads handoff We need barriers to guarantee this pattern works as intended: [w] req->rc, 1 [r] req->status, 1 wmb rmb [w] req->status, 1 [r] req->rc Where the wmb ensures that rc gets written before status, and the rmb ensures that if you observe status == 1, rc is the new value. Signed-off-by: Dominique Martinet Signed-off-by: Eric Van Hensbergen --- include/net/9p/client.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/9p/client.h b/include/net/9p/client.h index c38a005bd0cf..115aeac401b1 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -261,7 +261,7 @@ int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode, int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status); int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl); struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); -void p9_client_cb(struct p9_client *c, struct p9_req_t *req); +void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status); int p9_parse_header(struct p9_fcall *, int32_t *, int8_t *, int16_t *, int); int p9stat_read(struct p9_client *, char *, int, struct p9_wstat *); -- cgit v1.2.3 From afd8d65411551839b7ab14a539d00075b2793451 Mon Sep 17 00:00:00 2001 From: Simon Derr Date: Mon, 10 Mar 2014 16:38:49 +0100 Subject: 9P: Add cancelled() to the transport functions. And move transport-specific code out of net/9p/client.c Signed-off-by: Simon Derr Signed-off-by: Eric Van Hensbergen --- include/net/9p/transport.h | 3 +++ net/9p/client.c | 9 +++------ net/9p/trans_fd.c | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h index 9a36d9297114..d9fa68f26c41 100644 --- a/include/net/9p/transport.h +++ b/include/net/9p/transport.h @@ -40,6 +40,8 @@ * @close: member function to discard a connection on this transport * @request: member function to issue a request to the transport * @cancel: member function to cancel a request (if it hasn't been sent) + * @cancelled: member function to notify that a cancelled request will not + * not receive a reply * * This is the basic API for a transport module which is registered by the * transport module with the 9P core network module and used by the client @@ -58,6 +60,7 @@ struct p9_trans_module { void (*close) (struct p9_client *); int (*request) (struct p9_client *, struct p9_req_t *req); int (*cancel) (struct p9_client *, struct p9_req_t *req); + int (*cancelled)(struct p9_client *, struct p9_req_t *req); int (*zc_request)(struct p9_client *, struct p9_req_t *, char *, char *, int , int, int, int); }; diff --git a/net/9p/client.c b/net/9p/client.c index ce26da95f63f..40e558172bbe 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -663,16 +663,13 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) if (IS_ERR(req)) return PTR_ERR(req); - /* * if we haven't received a response for oldreq, * remove it from the list */ - if (oldreq->status == REQ_STATUS_FLSH) { - spin_lock(&c->lock); - list_del(&oldreq->req_list); - spin_unlock(&c->lock); - } + if (oldreq->status == REQ_STATUS_FLSH) + if (c->trans_mod->cancelled) + c->trans_mod->cancelled(c, oldreq); p9_free_req(c, req); return 0; diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 193efd562466..fda4951c869e 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -709,6 +709,20 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) return ret; } +static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) +{ + p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); + + /* we haven't received a response for oldreq, + * remove it from the list. + */ + spin_lock(&client->lock); + list_del(&req->req_list); + spin_unlock(&client->lock); + + return 0; +} + /** * parse_opts - parse mount options into p9_fd_opts structure * @params: options string passed from mount @@ -1050,6 +1064,7 @@ static struct p9_trans_module p9_tcp_trans = { .close = p9_fd_close, .request = p9_fd_request, .cancel = p9_fd_cancel, + .cancelled = p9_fd_cancelled, .owner = THIS_MODULE, }; @@ -1061,6 +1076,7 @@ static struct p9_trans_module p9_unix_trans = { .close = p9_fd_close, .request = p9_fd_request, .cancel = p9_fd_cancel, + .cancelled = p9_fd_cancelled, .owner = THIS_MODULE, }; @@ -1072,6 +1088,7 @@ static struct p9_trans_module p9_fd_trans = { .close = p9_fd_close, .request = p9_fd_request, .cancel = p9_fd_cancel, + .cancelled = p9_fd_cancelled, .owner = THIS_MODULE, }; -- cgit v1.2.3 From 0bfd6845c0b5e3df3507d2b4d230478980e7f04a Mon Sep 17 00:00:00 2001 From: Simon Derr Date: Mon, 10 Mar 2014 16:38:52 +0100 Subject: 9P: Get rid of REQ_STATUS_FLSH This request state is mostly useless, and properly implementing it for RDMA would require an extra lock to be taken in handle_recv() and in rdma_cancel() to avoid this race: handle_recv() rdma_cancel() . . . if req->state == SENT req->state = RCVD . . req->state = FLSH So just get rid of it. Signed-off-by: Simon Derr Signed-off-by: Eric Van Hensbergen --- include/net/9p/client.h | 2 -- net/9p/client.c | 2 +- net/9p/trans_fd.c | 7 ++----- 3 files changed, 3 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 115aeac401b1..81790a6fc663 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -67,7 +67,6 @@ enum p9_trans_status { * @REQ_STATUS_ALLOC: request has been allocated but not sent * @REQ_STATUS_UNSENT: request waiting to be sent * @REQ_STATUS_SENT: request sent to server - * @REQ_STATUS_FLSH: a flush has been sent for this request * @REQ_STATUS_RCVD: response received from server * @REQ_STATUS_FLSHD: request has been flushed * @REQ_STATUS_ERROR: request encountered an error on the client side @@ -83,7 +82,6 @@ enum p9_req_status_t { REQ_STATUS_ALLOC, REQ_STATUS_UNSENT, REQ_STATUS_SENT, - REQ_STATUS_FLSH, REQ_STATUS_RCVD, REQ_STATUS_FLSHD, REQ_STATUS_ERROR, diff --git a/net/9p/client.c b/net/9p/client.c index 40e558172bbe..0004cbaac4a4 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -667,7 +667,7 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) * if we haven't received a response for oldreq, * remove it from the list */ - if (oldreq->status == REQ_STATUS_FLSH) + if (oldreq->status == REQ_STATUS_SENT) if (c->trans_mod->cancelled) c->trans_mod->cancelled(c, oldreq); diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index fda4951c869e..9c806428e91a 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -345,8 +345,7 @@ static void p9_read_work(struct work_struct *work) "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); m->req = p9_tag_lookup(m->client, tag); - if (!m->req || (m->req->status != REQ_STATUS_SENT && - m->req->status != REQ_STATUS_FLSH)) { + if (!m->req || (m->req->status != REQ_STATUS_SENT)) { p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", tag); err = -EIO; @@ -701,9 +700,7 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) list_del(&req->req_list); req->status = REQ_STATUS_FLSHD; ret = 0; - } else if (req->status == REQ_STATUS_SENT) - req->status = REQ_STATUS_FLSH; - + } spin_unlock(&client->lock); return ret; -- cgit v1.2.3 From 7b4f307276ae3f69fc4d7c4fb6a188c906755d98 Mon Sep 17 00:00:00 2001 From: Simon Derr Date: Tue, 11 Mar 2014 10:13:08 +0100 Subject: 9pnet: p9_client->conn field is unused. Remove it. Signed-off-by: Simon Derr Signed-off-by: Eric Van Hensbergen --- include/net/9p/client.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 81790a6fc663..6fab66c5c5af 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -128,7 +128,6 @@ struct p9_req_t { * @proto_version: 9P protocol version to use * @trans_mod: module API instantiated with this client * @trans: tranport instance state and API - * @conn: connection state information used by trans_fd * @fidpool: fid handle accounting for session * @fidlist: List of active fid handles * @tagpool - transaction id accounting for session @@ -157,7 +156,6 @@ struct p9_client { struct p9_trans_module *trans_mod; enum p9_trans_status status; void *trans; - struct p9_conn *conn; struct p9_idpool *fidpool; struct list_head fidlist; -- cgit v1.2.3