diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-11 17:14:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-11 17:14:57 -0400 |
commit | 582076ab16779208e7eb6ce712a9c0a6cc5bafe4 (patch) | |
tree | 6841c02fa19dba9c4a8299592a7f14344f8944f7 /net | |
parent | 79d2d21ee06f3634423d1a45fb6ddfcae59061fd (diff) | |
parent | 8a5daf1e2c199746767d94b4036638ba11d528b3 (diff) |
Merge tag 'for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
Pull 9p changes from Eric Van Hensbergen:
"A bunch of updates and cleanup within the transport layer,
particularly with a focus on RDMA"
* tag 'for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs:
9pnet_rdma: check token type before int conversion
9pnet: trans_fd : allocate struct p9_trans_fd and struct p9_conn together.
9pnet: p9_client->conn field is unused. Remove it.
9P: Get rid of REQ_STATUS_FLSH
9pnet_rdma: add cancelled()
9pnet_rdma: update request status during send
9P: Add cancelled() to the transport functions.
net: Mark function as static in 9p/client.c
9P: Add memory barriers to protect request fields over cb/rpc threads handoff
Diffstat (limited to 'net')
-rw-r--r-- | net/9p/client.c | 25 | ||||
-rw-r--r-- | net/9p/trans_fd.c | 110 | ||||
-rw-r--r-- | net/9p/trans_rdma.c | 26 | ||||
-rw-r--r-- | net/9p/trans_virtio.c | 3 |
4 files changed, 92 insertions, 72 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 9186550d77a6..0004cbaac4a4 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -415,9 +415,17 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r) | |||
415 | * req: request received | 415 | * req: request received |
416 | * | 416 | * |
417 | */ | 417 | */ |
418 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req) | 418 | void p9_client_cb(struct p9_client *c, struct p9_req_t *req, int status) |
419 | { | 419 | { |
420 | p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); | 420 | p9_debug(P9_DEBUG_MUX, " tag %d\n", req->tc->tag); |
421 | |||
422 | /* | ||
423 | * This barrier is needed to make sure any change made to req before | ||
424 | * the other thread wakes up will indeed be seen by the waiting side. | ||
425 | */ | ||
426 | smp_wmb(); | ||
427 | req->status = status; | ||
428 | |||
421 | wake_up(req->wq); | 429 | wake_up(req->wq); |
422 | p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); | 430 | p9_debug(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag); |
423 | } | 431 | } |
@@ -655,16 +663,13 @@ static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq) | |||
655 | if (IS_ERR(req)) | 663 | if (IS_ERR(req)) |
656 | return PTR_ERR(req); | 664 | return PTR_ERR(req); |
657 | 665 | ||
658 | |||
659 | /* | 666 | /* |
660 | * if we haven't received a response for oldreq, | 667 | * if we haven't received a response for oldreq, |
661 | * remove it from the list | 668 | * remove it from the list |
662 | */ | 669 | */ |
663 | if (oldreq->status == REQ_STATUS_FLSH) { | 670 | if (oldreq->status == REQ_STATUS_SENT) |
664 | spin_lock(&c->lock); | 671 | if (c->trans_mod->cancelled) |
665 | list_del(&oldreq->req_list); | 672 | c->trans_mod->cancelled(c, oldreq); |
666 | spin_unlock(&c->lock); | ||
667 | } | ||
668 | 673 | ||
669 | p9_free_req(c, req); | 674 | p9_free_req(c, req); |
670 | return 0; | 675 | return 0; |
@@ -751,6 +756,12 @@ again: | |||
751 | err = wait_event_interruptible(*req->wq, | 756 | err = wait_event_interruptible(*req->wq, |
752 | req->status >= REQ_STATUS_RCVD); | 757 | req->status >= REQ_STATUS_RCVD); |
753 | 758 | ||
759 | /* | ||
760 | * Make sure our req is coherent with regard to updates in other | ||
761 | * threads - echoes to wmb() in the callback | ||
762 | */ | ||
763 | smp_rmb(); | ||
764 | |||
754 | if ((err == -ERESTARTSYS) && (c->status == Connected) | 765 | if ((err == -ERESTARTSYS) && (c->status == Connected) |
755 | && (type == P9_TFLUSH)) { | 766 | && (type == P9_TFLUSH)) { |
756 | sigpending = 1; | 767 | sigpending = 1; |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index b7bd7f2961bf..80d08f6664cb 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -66,20 +66,6 @@ struct p9_fd_opts { | |||
66 | int privport; | 66 | int privport; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | /** | ||
70 | * struct p9_trans_fd - transport state | ||
71 | * @rd: reference to file to read from | ||
72 | * @wr: reference of file to write to | ||
73 | * @conn: connection state reference | ||
74 | * | ||
75 | */ | ||
76 | |||
77 | struct p9_trans_fd { | ||
78 | struct file *rd; | ||
79 | struct file *wr; | ||
80 | struct p9_conn *conn; | ||
81 | }; | ||
82 | |||
83 | /* | 69 | /* |
84 | * Option Parsing (code inspired by NFS code) | 70 | * Option Parsing (code inspired by NFS code) |
85 | * - a little lazy - parse all fd-transport options | 71 | * - a little lazy - parse all fd-transport options |
@@ -159,6 +145,20 @@ struct p9_conn { | |||
159 | unsigned long wsched; | 145 | unsigned long wsched; |
160 | }; | 146 | }; |
161 | 147 | ||
148 | /** | ||
149 | * struct p9_trans_fd - transport state | ||
150 | * @rd: reference to file to read from | ||
151 | * @wr: reference of file to write to | ||
152 | * @conn: connection state reference | ||
153 | * | ||
154 | */ | ||
155 | |||
156 | struct p9_trans_fd { | ||
157 | struct file *rd; | ||
158 | struct file *wr; | ||
159 | struct p9_conn conn; | ||
160 | }; | ||
161 | |||
162 | static void p9_poll_workfn(struct work_struct *work); | 162 | static void p9_poll_workfn(struct work_struct *work); |
163 | 163 | ||
164 | static DEFINE_SPINLOCK(p9_poll_lock); | 164 | static DEFINE_SPINLOCK(p9_poll_lock); |
@@ -212,15 +212,9 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
212 | m->err = err; | 212 | m->err = err; |
213 | 213 | ||
214 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { | 214 | list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { |
215 | req->status = REQ_STATUS_ERROR; | ||
216 | if (!req->t_err) | ||
217 | req->t_err = err; | ||
218 | list_move(&req->req_list, &cancel_list); | 215 | list_move(&req->req_list, &cancel_list); |
219 | } | 216 | } |
220 | list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { | 217 | list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) { |
221 | req->status = REQ_STATUS_ERROR; | ||
222 | if (!req->t_err) | ||
223 | req->t_err = err; | ||
224 | list_move(&req->req_list, &cancel_list); | 218 | list_move(&req->req_list, &cancel_list); |
225 | } | 219 | } |
226 | spin_unlock_irqrestore(&m->client->lock, flags); | 220 | spin_unlock_irqrestore(&m->client->lock, flags); |
@@ -228,7 +222,9 @@ static void p9_conn_cancel(struct p9_conn *m, int err) | |||
228 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { | 222 | list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) { |
229 | p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); | 223 | p9_debug(P9_DEBUG_ERROR, "call back req %p\n", req); |
230 | list_del(&req->req_list); | 224 | list_del(&req->req_list); |
231 | p9_client_cb(m->client, req); | 225 | if (!req->t_err) |
226 | req->t_err = err; | ||
227 | p9_client_cb(m->client, req, REQ_STATUS_ERROR); | ||
232 | } | 228 | } |
233 | } | 229 | } |
234 | 230 | ||
@@ -302,6 +298,7 @@ static void p9_read_work(struct work_struct *work) | |||
302 | { | 298 | { |
303 | int n, err; | 299 | int n, err; |
304 | struct p9_conn *m; | 300 | struct p9_conn *m; |
301 | int status = REQ_STATUS_ERROR; | ||
305 | 302 | ||
306 | m = container_of(work, struct p9_conn, rq); | 303 | m = container_of(work, struct p9_conn, rq); |
307 | 304 | ||
@@ -348,8 +345,7 @@ static void p9_read_work(struct work_struct *work) | |||
348 | "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); | 345 | "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag); |
349 | 346 | ||
350 | m->req = p9_tag_lookup(m->client, tag); | 347 | m->req = p9_tag_lookup(m->client, tag); |
351 | if (!m->req || (m->req->status != REQ_STATUS_SENT && | 348 | if (!m->req || (m->req->status != REQ_STATUS_SENT)) { |
352 | m->req->status != REQ_STATUS_FLSH)) { | ||
353 | p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", | 349 | p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", |
354 | tag); | 350 | tag); |
355 | err = -EIO; | 351 | err = -EIO; |
@@ -375,10 +371,10 @@ static void p9_read_work(struct work_struct *work) | |||
375 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); | 371 | p9_debug(P9_DEBUG_TRANS, "got new packet\n"); |
376 | spin_lock(&m->client->lock); | 372 | spin_lock(&m->client->lock); |
377 | if (m->req->status != REQ_STATUS_ERROR) | 373 | if (m->req->status != REQ_STATUS_ERROR) |
378 | m->req->status = REQ_STATUS_RCVD; | 374 | status = REQ_STATUS_RCVD; |
379 | list_del(&m->req->req_list); | 375 | list_del(&m->req->req_list); |
380 | spin_unlock(&m->client->lock); | 376 | spin_unlock(&m->client->lock); |
381 | p9_client_cb(m->client, m->req); | 377 | p9_client_cb(m->client, m->req, status); |
382 | m->rbuf = NULL; | 378 | m->rbuf = NULL; |
383 | m->rpos = 0; | 379 | m->rpos = 0; |
384 | m->rsize = 0; | 380 | m->rsize = 0; |
@@ -573,21 +569,19 @@ p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p) | |||
573 | } | 569 | } |
574 | 570 | ||
575 | /** | 571 | /** |
576 | * p9_conn_create - allocate and initialize the per-session mux data | 572 | * p9_conn_create - initialize the per-session mux data |
577 | * @client: client instance | 573 | * @client: client instance |
578 | * | 574 | * |
579 | * Note: Creates the polling task if this is the first session. | 575 | * Note: Creates the polling task if this is the first session. |
580 | */ | 576 | */ |
581 | 577 | ||
582 | static struct p9_conn *p9_conn_create(struct p9_client *client) | 578 | static void p9_conn_create(struct p9_client *client) |
583 | { | 579 | { |
584 | int n; | 580 | int n; |
585 | struct p9_conn *m; | 581 | struct p9_trans_fd *ts = client->trans; |
582 | struct p9_conn *m = &ts->conn; | ||
586 | 583 | ||
587 | p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize); | 584 | p9_debug(P9_DEBUG_TRANS, "client %p msize %d\n", client, client->msize); |
588 | m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL); | ||
589 | if (!m) | ||
590 | return ERR_PTR(-ENOMEM); | ||
591 | 585 | ||
592 | INIT_LIST_HEAD(&m->mux_list); | 586 | INIT_LIST_HEAD(&m->mux_list); |
593 | m->client = client; | 587 | m->client = client; |
@@ -609,8 +603,6 @@ static struct p9_conn *p9_conn_create(struct p9_client *client) | |||
609 | p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m); | 603 | p9_debug(P9_DEBUG_TRANS, "mux %p can write\n", m); |
610 | set_bit(Wpending, &m->wsched); | 604 | set_bit(Wpending, &m->wsched); |
611 | } | 605 | } |
612 | |||
613 | return m; | ||
614 | } | 606 | } |
615 | 607 | ||
616 | /** | 608 | /** |
@@ -669,7 +661,7 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) | |||
669 | { | 661 | { |
670 | int n; | 662 | int n; |
671 | struct p9_trans_fd *ts = client->trans; | 663 | struct p9_trans_fd *ts = client->trans; |
672 | struct p9_conn *m = ts->conn; | 664 | struct p9_conn *m = &ts->conn; |
673 | 665 | ||
674 | p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", | 666 | p9_debug(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", |
675 | m, current, req->tc, req->tc->id); | 667 | m, current, req->tc, req->tc->id); |
@@ -704,14 +696,26 @@ static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req) | |||
704 | list_del(&req->req_list); | 696 | list_del(&req->req_list); |
705 | req->status = REQ_STATUS_FLSHD; | 697 | req->status = REQ_STATUS_FLSHD; |
706 | ret = 0; | 698 | ret = 0; |
707 | } else if (req->status == REQ_STATUS_SENT) | 699 | } |
708 | req->status = REQ_STATUS_FLSH; | ||
709 | |||
710 | spin_unlock(&client->lock); | 700 | spin_unlock(&client->lock); |
711 | 701 | ||
712 | return ret; | 702 | return ret; |
713 | } | 703 | } |
714 | 704 | ||
705 | static int p9_fd_cancelled(struct p9_client *client, struct p9_req_t *req) | ||
706 | { | ||
707 | p9_debug(P9_DEBUG_TRANS, "client %p req %p\n", client, req); | ||
708 | |||
709 | /* we haven't received a response for oldreq, | ||
710 | * remove it from the list. | ||
711 | */ | ||
712 | spin_lock(&client->lock); | ||
713 | list_del(&req->req_list); | ||
714 | spin_unlock(&client->lock); | ||
715 | |||
716 | return 0; | ||
717 | } | ||
718 | |||
715 | /** | 719 | /** |
716 | * parse_opts - parse mount options into p9_fd_opts structure | 720 | * parse_opts - parse mount options into p9_fd_opts structure |
717 | * @params: options string passed from mount | 721 | * @params: options string passed from mount |
@@ -780,7 +784,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
780 | 784 | ||
781 | static int p9_fd_open(struct p9_client *client, int rfd, int wfd) | 785 | static int p9_fd_open(struct p9_client *client, int rfd, int wfd) |
782 | { | 786 | { |
783 | struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd), | 787 | struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd), |
784 | GFP_KERNEL); | 788 | GFP_KERNEL); |
785 | if (!ts) | 789 | if (!ts) |
786 | return -ENOMEM; | 790 | return -ENOMEM; |
@@ -806,9 +810,8 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) | |||
806 | { | 810 | { |
807 | struct p9_trans_fd *p; | 811 | struct p9_trans_fd *p; |
808 | struct file *file; | 812 | struct file *file; |
809 | int ret; | ||
810 | 813 | ||
811 | p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); | 814 | p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); |
812 | if (!p) | 815 | if (!p) |
813 | return -ENOMEM; | 816 | return -ENOMEM; |
814 | 817 | ||
@@ -829,20 +832,12 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) | |||
829 | 832 | ||
830 | p->rd->f_flags |= O_NONBLOCK; | 833 | p->rd->f_flags |= O_NONBLOCK; |
831 | 834 | ||
832 | p->conn = p9_conn_create(client); | 835 | p9_conn_create(client); |
833 | if (IS_ERR(p->conn)) { | ||
834 | ret = PTR_ERR(p->conn); | ||
835 | p->conn = NULL; | ||
836 | kfree(p); | ||
837 | sockfd_put(csocket); | ||
838 | sockfd_put(csocket); | ||
839 | return ret; | ||
840 | } | ||
841 | return 0; | 836 | return 0; |
842 | } | 837 | } |
843 | 838 | ||
844 | /** | 839 | /** |
845 | * p9_mux_destroy - cancels all pending requests and frees mux resources | 840 | * p9_mux_destroy - cancels all pending requests of mux |
846 | * @m: mux to destroy | 841 | * @m: mux to destroy |
847 | * | 842 | * |
848 | */ | 843 | */ |
@@ -859,7 +854,6 @@ static void p9_conn_destroy(struct p9_conn *m) | |||
859 | p9_conn_cancel(m, -ECONNRESET); | 854 | p9_conn_cancel(m, -ECONNRESET); |
860 | 855 | ||
861 | m->client = NULL; | 856 | m->client = NULL; |
862 | kfree(m); | ||
863 | } | 857 | } |
864 | 858 | ||
865 | /** | 859 | /** |
@@ -881,7 +875,7 @@ static void p9_fd_close(struct p9_client *client) | |||
881 | 875 | ||
882 | client->status = Disconnected; | 876 | client->status = Disconnected; |
883 | 877 | ||
884 | p9_conn_destroy(ts->conn); | 878 | p9_conn_destroy(&ts->conn); |
885 | 879 | ||
886 | if (ts->rd) | 880 | if (ts->rd) |
887 | fput(ts->rd); | 881 | fput(ts->rd); |
@@ -1033,14 +1027,7 @@ p9_fd_create(struct p9_client *client, const char *addr, char *args) | |||
1033 | return err; | 1027 | return err; |
1034 | 1028 | ||
1035 | p = (struct p9_trans_fd *) client->trans; | 1029 | p = (struct p9_trans_fd *) client->trans; |
1036 | p->conn = p9_conn_create(client); | 1030 | p9_conn_create(client); |
1037 | if (IS_ERR(p->conn)) { | ||
1038 | err = PTR_ERR(p->conn); | ||
1039 | p->conn = NULL; | ||
1040 | fput(p->rd); | ||
1041 | fput(p->wr); | ||
1042 | return err; | ||
1043 | } | ||
1044 | 1031 | ||
1045 | return 0; | 1032 | return 0; |
1046 | } | 1033 | } |
@@ -1053,6 +1040,7 @@ static struct p9_trans_module p9_tcp_trans = { | |||
1053 | .close = p9_fd_close, | 1040 | .close = p9_fd_close, |
1054 | .request = p9_fd_request, | 1041 | .request = p9_fd_request, |
1055 | .cancel = p9_fd_cancel, | 1042 | .cancel = p9_fd_cancel, |
1043 | .cancelled = p9_fd_cancelled, | ||
1056 | .owner = THIS_MODULE, | 1044 | .owner = THIS_MODULE, |
1057 | }; | 1045 | }; |
1058 | 1046 | ||
@@ -1064,6 +1052,7 @@ static struct p9_trans_module p9_unix_trans = { | |||
1064 | .close = p9_fd_close, | 1052 | .close = p9_fd_close, |
1065 | .request = p9_fd_request, | 1053 | .request = p9_fd_request, |
1066 | .cancel = p9_fd_cancel, | 1054 | .cancel = p9_fd_cancel, |
1055 | .cancelled = p9_fd_cancelled, | ||
1067 | .owner = THIS_MODULE, | 1056 | .owner = THIS_MODULE, |
1068 | }; | 1057 | }; |
1069 | 1058 | ||
@@ -1075,6 +1064,7 @@ static struct p9_trans_module p9_fd_trans = { | |||
1075 | .close = p9_fd_close, | 1064 | .close = p9_fd_close, |
1076 | .request = p9_fd_request, | 1065 | .request = p9_fd_request, |
1077 | .cancel = p9_fd_cancel, | 1066 | .cancel = p9_fd_cancel, |
1067 | .cancelled = p9_fd_cancelled, | ||
1078 | .owner = THIS_MODULE, | 1068 | .owner = THIS_MODULE, |
1079 | }; | 1069 | }; |
1080 | 1070 | ||
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 8f68df5d2973..14ad43b5cf89 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
@@ -193,6 +193,8 @@ static int parse_opts(char *params, struct p9_rdma_opts *opts) | |||
193 | if (!*p) | 193 | if (!*p) |
194 | continue; | 194 | continue; |
195 | token = match_token(p, tokens, args); | 195 | token = match_token(p, tokens, args); |
196 | if (token == Opt_err) | ||
197 | continue; | ||
196 | r = match_int(&args[0], &option); | 198 | r = match_int(&args[0], &option); |
197 | if (r < 0) { | 199 | if (r < 0) { |
198 | p9_debug(P9_DEBUG_ERROR, | 200 | p9_debug(P9_DEBUG_ERROR, |
@@ -305,8 +307,7 @@ handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma, | |||
305 | } | 307 | } |
306 | 308 | ||
307 | req->rc = c->rc; | 309 | req->rc = c->rc; |
308 | req->status = REQ_STATUS_RCVD; | 310 | p9_client_cb(client, req, REQ_STATUS_RCVD); |
309 | p9_client_cb(client, req); | ||
310 | 311 | ||
311 | return; | 312 | return; |
312 | 313 | ||
@@ -511,6 +512,11 @@ dont_need_post_recv: | |||
511 | goto send_error; | 512 | goto send_error; |
512 | } | 513 | } |
513 | 514 | ||
515 | /* Mark request as `sent' *before* we actually send it, | ||
516 | * because doing if after could erase the REQ_STATUS_RCVD | ||
517 | * status in case of a very fast reply. | ||
518 | */ | ||
519 | req->status = REQ_STATUS_SENT; | ||
514 | err = ib_post_send(rdma->qp, &wr, &bad_wr); | 520 | err = ib_post_send(rdma->qp, &wr, &bad_wr); |
515 | if (err) | 521 | if (err) |
516 | goto send_error; | 522 | goto send_error; |
@@ -520,6 +526,7 @@ dont_need_post_recv: | |||
520 | 526 | ||
521 | /* Handle errors that happened during or while preparing the send: */ | 527 | /* Handle errors that happened during or while preparing the send: */ |
522 | send_error: | 528 | send_error: |
529 | req->status = REQ_STATUS_ERROR; | ||
523 | kfree(c); | 530 | kfree(c); |
524 | p9_debug(P9_DEBUG_ERROR, "Error %d in rdma_request()\n", err); | 531 | p9_debug(P9_DEBUG_ERROR, "Error %d in rdma_request()\n", err); |
525 | 532 | ||
@@ -582,12 +589,24 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts) | |||
582 | return rdma; | 589 | return rdma; |
583 | } | 590 | } |
584 | 591 | ||
585 | /* its not clear to me we can do anything after send has been posted */ | ||
586 | static int rdma_cancel(struct p9_client *client, struct p9_req_t *req) | 592 | static int rdma_cancel(struct p9_client *client, struct p9_req_t *req) |
587 | { | 593 | { |
594 | /* Nothing to do here. | ||
595 | * We will take care of it (if we have to) in rdma_cancelled() | ||
596 | */ | ||
588 | return 1; | 597 | return 1; |
589 | } | 598 | } |
590 | 599 | ||
600 | /* A request has been fully flushed without a reply. | ||
601 | * That means we have posted one buffer in excess. | ||
602 | */ | ||
603 | static int rdma_cancelled(struct p9_client *client, struct p9_req_t *req) | ||
604 | { | ||
605 | struct p9_trans_rdma *rdma = client->trans; | ||
606 | atomic_inc(&rdma->excess_rc); | ||
607 | return 0; | ||
608 | } | ||
609 | |||
591 | /** | 610 | /** |
592 | * trans_create_rdma - Transport method for creating atransport instance | 611 | * trans_create_rdma - Transport method for creating atransport instance |
593 | * @client: client instance | 612 | * @client: client instance |
@@ -721,6 +740,7 @@ static struct p9_trans_module p9_rdma_trans = { | |||
721 | .close = rdma_close, | 740 | .close = rdma_close, |
722 | .request = rdma_request, | 741 | .request = rdma_request, |
723 | .cancel = rdma_cancel, | 742 | .cancel = rdma_cancel, |
743 | .cancelled = rdma_cancelled, | ||
724 | }; | 744 | }; |
725 | 745 | ||
726 | /** | 746 | /** |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index ac2666c1d011..6940d8fe8971 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -164,8 +164,7 @@ static void req_done(struct virtqueue *vq) | |||
164 | p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc); | 164 | p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc); |
165 | p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag); | 165 | p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag); |
166 | req = p9_tag_lookup(chan->client, rc->tag); | 166 | req = p9_tag_lookup(chan->client, rc->tag); |
167 | req->status = REQ_STATUS_RCVD; | 167 | p9_client_cb(chan->client, req, REQ_STATUS_RCVD); |
168 | p9_client_cb(chan->client, req); | ||
169 | } | 168 | } |
170 | } | 169 | } |
171 | 170 | ||