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/9p | |
| 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/9p')
| -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 | ||
