aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hidp/core.c197
-rw-r--r--net/bluetooth/hidp/hidp.h15
-rw-r--r--net/core/dev_addr_lists.c4
-rw-r--r--net/ipv6/inet6_hashtables.c2
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c2
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c2
-rw-r--r--net/sunrpc/clnt.c18
-rw-r--r--net/sunrpc/sched.c29
-rw-r--r--net/sunrpc/xprt.c25
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c86
-rw-r--r--net/sunrpc/xprtrdma/verbs.c53
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h1
13 files changed, 320 insertions, 116 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 2429ca2d7b06..5ec12971af6b 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -36,6 +36,7 @@
36#include <linux/file.h> 36#include <linux/file.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/wait.h> 38#include <linux/wait.h>
39#include <linux/mutex.h>
39#include <net/sock.h> 40#include <net/sock.h>
40 41
41#include <linux/input.h> 42#include <linux/input.h>
@@ -316,24 +317,144 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
316 return hidp_queue_report(session, buf, rsize); 317 return hidp_queue_report(session, buf, rsize);
317} 318}
318 319
320static int hidp_get_raw_report(struct hid_device *hid,
321 unsigned char report_number,
322 unsigned char *data, size_t count,
323 unsigned char report_type)
324{
325 struct hidp_session *session = hid->driver_data;
326 struct sk_buff *skb;
327 size_t len;
328 int numbered_reports = hid->report_enum[report_type].numbered;
329
330 switch (report_type) {
331 case HID_FEATURE_REPORT:
332 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_FEATURE;
333 break;
334 case HID_INPUT_REPORT:
335 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_INPUT;
336 break;
337 case HID_OUTPUT_REPORT:
338 report_type = HIDP_TRANS_GET_REPORT | HIDP_DATA_RTYPE_OUPUT;
339 break;
340 default:
341 return -EINVAL;
342 }
343
344 if (mutex_lock_interruptible(&session->report_mutex))
345 return -ERESTARTSYS;
346
347 /* Set up our wait, and send the report request to the device. */
348 session->waiting_report_type = report_type & HIDP_DATA_RTYPE_MASK;
349 session->waiting_report_number = numbered_reports ? report_number : -1;
350 set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
351 data[0] = report_number;
352 if (hidp_send_ctrl_message(hid->driver_data, report_type, data, 1))
353 goto err_eio;
354
355 /* Wait for the return of the report. The returned report
356 gets put in session->report_return. */
357 while (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
358 int res;
359
360 res = wait_event_interruptible_timeout(session->report_queue,
361 !test_bit(HIDP_WAITING_FOR_RETURN, &session->flags),
362 5*HZ);
363 if (res == 0) {
364 /* timeout */
365 goto err_eio;
366 }
367 if (res < 0) {
368 /* signal */
369 goto err_restartsys;
370 }
371 }
372
373 skb = session->report_return;
374 if (skb) {
375 len = skb->len < count ? skb->len : count;
376 memcpy(data, skb->data, len);
377
378 kfree_skb(skb);
379 session->report_return = NULL;
380 } else {
381 /* Device returned a HANDSHAKE, indicating protocol error. */
382 len = -EIO;
383 }
384
385 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
386 mutex_unlock(&session->report_mutex);
387
388 return len;
389
390err_restartsys:
391 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
392 mutex_unlock(&session->report_mutex);
393 return -ERESTARTSYS;
394err_eio:
395 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
396 mutex_unlock(&session->report_mutex);
397 return -EIO;
398}
399
319static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count, 400static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, size_t count,
320 unsigned char report_type) 401 unsigned char report_type)
321{ 402{
403 struct hidp_session *session = hid->driver_data;
404 int ret;
405
322 switch (report_type) { 406 switch (report_type) {
323 case HID_FEATURE_REPORT: 407 case HID_FEATURE_REPORT:
324 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE; 408 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
325 break; 409 break;
326 case HID_OUTPUT_REPORT: 410 case HID_OUTPUT_REPORT:
327 report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT; 411 report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
328 break; 412 break;
329 default: 413 default:
330 return -EINVAL; 414 return -EINVAL;
331 } 415 }
332 416
417 if (mutex_lock_interruptible(&session->report_mutex))
418 return -ERESTARTSYS;
419
420 /* Set up our wait, and send the report request to the device. */
421 set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
333 if (hidp_send_ctrl_message(hid->driver_data, report_type, 422 if (hidp_send_ctrl_message(hid->driver_data, report_type,
334 data, count)) 423 data, count)) {
335 return -ENOMEM; 424 ret = -ENOMEM;
336 return count; 425 goto err;
426 }
427
428 /* Wait for the ACK from the device. */
429 while (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) {
430 int res;
431
432 res = wait_event_interruptible_timeout(session->report_queue,
433 !test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags),
434 10*HZ);
435 if (res == 0) {
436 /* timeout */
437 ret = -EIO;
438 goto err;
439 }
440 if (res < 0) {
441 /* signal */
442 ret = -ERESTARTSYS;
443 goto err;
444 }
445 }
446
447 if (!session->output_report_success) {
448 ret = -EIO;
449 goto err;
450 }
451
452 ret = count;
453
454err:
455 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
456 mutex_unlock(&session->report_mutex);
457 return ret;
337} 458}
338 459
339static void hidp_idle_timeout(unsigned long arg) 460static void hidp_idle_timeout(unsigned long arg)
@@ -360,16 +481,22 @@ static void hidp_process_handshake(struct hidp_session *session,
360 unsigned char param) 481 unsigned char param)
361{ 482{
362 BT_DBG("session %p param 0x%02x", session, param); 483 BT_DBG("session %p param 0x%02x", session, param);
484 session->output_report_success = 0; /* default condition */
363 485
364 switch (param) { 486 switch (param) {
365 case HIDP_HSHK_SUCCESSFUL: 487 case HIDP_HSHK_SUCCESSFUL:
366 /* FIXME: Call into SET_ GET_ handlers here */ 488 /* FIXME: Call into SET_ GET_ handlers here */
489 session->output_report_success = 1;
367 break; 490 break;
368 491
369 case HIDP_HSHK_NOT_READY: 492 case HIDP_HSHK_NOT_READY:
370 case HIDP_HSHK_ERR_INVALID_REPORT_ID: 493 case HIDP_HSHK_ERR_INVALID_REPORT_ID:
371 case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST: 494 case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
372 case HIDP_HSHK_ERR_INVALID_PARAMETER: 495 case HIDP_HSHK_ERR_INVALID_PARAMETER:
496 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags)) {
497 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
498 wake_up_interruptible(&session->report_queue);
499 }
373 /* FIXME: Call into SET_ GET_ handlers here */ 500 /* FIXME: Call into SET_ GET_ handlers here */
374 break; 501 break;
375 502
@@ -388,6 +515,12 @@ static void hidp_process_handshake(struct hidp_session *session,
388 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); 515 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
389 break; 516 break;
390 } 517 }
518
519 /* Wake up the waiting thread. */
520 if (test_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags)) {
521 clear_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
522 wake_up_interruptible(&session->report_queue);
523 }
391} 524}
392 525
393static void hidp_process_hid_control(struct hidp_session *session, 526static void hidp_process_hid_control(struct hidp_session *session,
@@ -406,9 +539,11 @@ static void hidp_process_hid_control(struct hidp_session *session,
406 } 539 }
407} 540}
408 541
409static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, 542/* Returns true if the passed-in skb should be freed by the caller. */
543static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
410 unsigned char param) 544 unsigned char param)
411{ 545{
546 int done_with_skb = 1;
412 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param); 547 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
413 548
414 switch (param) { 549 switch (param) {
@@ -420,7 +555,6 @@ static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
420 555
421 if (session->hid) 556 if (session->hid)
422 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0); 557 hid_input_report(session->hid, HID_INPUT_REPORT, skb->data, skb->len, 0);
423
424 break; 558 break;
425 559
426 case HIDP_DATA_RTYPE_OTHER: 560 case HIDP_DATA_RTYPE_OTHER:
@@ -432,12 +566,27 @@ static void hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
432 __hidp_send_ctrl_message(session, 566 __hidp_send_ctrl_message(session,
433 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0); 567 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
434 } 568 }
569
570 if (test_bit(HIDP_WAITING_FOR_RETURN, &session->flags) &&
571 param == session->waiting_report_type) {
572 if (session->waiting_report_number < 0 ||
573 session->waiting_report_number == skb->data[0]) {
574 /* hidp_get_raw_report() is waiting on this report. */
575 session->report_return = skb;
576 done_with_skb = 0;
577 clear_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
578 wake_up_interruptible(&session->report_queue);
579 }
580 }
581
582 return done_with_skb;
435} 583}
436 584
437static void hidp_recv_ctrl_frame(struct hidp_session *session, 585static void hidp_recv_ctrl_frame(struct hidp_session *session,
438 struct sk_buff *skb) 586 struct sk_buff *skb)
439{ 587{
440 unsigned char hdr, type, param; 588 unsigned char hdr, type, param;
589 int free_skb = 1;
441 590
442 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 591 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
443 592
@@ -457,7 +606,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
457 break; 606 break;
458 607
459 case HIDP_TRANS_DATA: 608 case HIDP_TRANS_DATA:
460 hidp_process_data(session, skb, param); 609 free_skb = hidp_process_data(session, skb, param);
461 break; 610 break;
462 611
463 default: 612 default:
@@ -466,7 +615,8 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
466 break; 615 break;
467 } 616 }
468 617
469 kfree_skb(skb); 618 if (free_skb)
619 kfree_skb(skb);
470} 620}
471 621
472static void hidp_recv_intr_frame(struct hidp_session *session, 622static void hidp_recv_intr_frame(struct hidp_session *session,
@@ -566,6 +716,8 @@ static int hidp_session(void *arg)
566 init_waitqueue_entry(&intr_wait, current); 716 init_waitqueue_entry(&intr_wait, current);
567 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait); 717 add_wait_queue(sk_sleep(ctrl_sk), &ctrl_wait);
568 add_wait_queue(sk_sleep(intr_sk), &intr_wait); 718 add_wait_queue(sk_sleep(intr_sk), &intr_wait);
719 session->waiting_for_startup = 0;
720 wake_up_interruptible(&session->startup_queue);
569 while (!atomic_read(&session->terminate)) { 721 while (!atomic_read(&session->terminate)) {
570 set_current_state(TASK_INTERRUPTIBLE); 722 set_current_state(TASK_INTERRUPTIBLE);
571 723
@@ -757,6 +909,8 @@ static struct hid_ll_driver hidp_hid_driver = {
757 .hidinput_input_event = hidp_hidinput_event, 909 .hidinput_input_event = hidp_hidinput_event,
758}; 910};
759 911
912/* This function sets up the hid device. It does not add it
913 to the HID system. That is done in hidp_add_connection(). */
760static int hidp_setup_hid(struct hidp_session *session, 914static int hidp_setup_hid(struct hidp_session *session,
761 struct hidp_connadd_req *req) 915 struct hidp_connadd_req *req)
762{ 916{
@@ -796,18 +950,11 @@ static int hidp_setup_hid(struct hidp_session *session,
796 hid->dev.parent = hidp_get_device(session); 950 hid->dev.parent = hidp_get_device(session);
797 hid->ll_driver = &hidp_hid_driver; 951 hid->ll_driver = &hidp_hid_driver;
798 952
953 hid->hid_get_raw_report = hidp_get_raw_report;
799 hid->hid_output_raw_report = hidp_output_raw_report; 954 hid->hid_output_raw_report = hidp_output_raw_report;
800 955
801 err = hid_add_device(hid);
802 if (err < 0)
803 goto failed;
804
805 return 0; 956 return 0;
806 957
807failed:
808 hid_destroy_device(hid);
809 session->hid = NULL;
810
811fault: 958fault:
812 kfree(session->rd_data); 959 kfree(session->rd_data);
813 session->rd_data = NULL; 960 session->rd_data = NULL;
@@ -856,6 +1003,10 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
856 skb_queue_head_init(&session->ctrl_transmit); 1003 skb_queue_head_init(&session->ctrl_transmit);
857 skb_queue_head_init(&session->intr_transmit); 1004 skb_queue_head_init(&session->intr_transmit);
858 1005
1006 mutex_init(&session->report_mutex);
1007 init_waitqueue_head(&session->report_queue);
1008 init_waitqueue_head(&session->startup_queue);
1009 session->waiting_for_startup = 1;
859 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 1010 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
860 session->idle_to = req->idle_to; 1011 session->idle_to = req->idle_to;
861 1012
@@ -878,6 +1029,14 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
878 err = kernel_thread(hidp_session, session, CLONE_KERNEL); 1029 err = kernel_thread(hidp_session, session, CLONE_KERNEL);
879 if (err < 0) 1030 if (err < 0)
880 goto unlink; 1031 goto unlink;
1032 while (session->waiting_for_startup) {
1033 wait_event_interruptible(session->startup_queue,
1034 !session->waiting_for_startup);
1035 }
1036
1037 err = hid_add_device(session->hid);
1038 if (err < 0)
1039 goto err_add_device;
881 1040
882 if (session->input) { 1041 if (session->input) {
883 hidp_send_ctrl_message(session, 1042 hidp_send_ctrl_message(session,
@@ -891,6 +1050,12 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
891 up_write(&hidp_session_sem); 1050 up_write(&hidp_session_sem);
892 return 0; 1051 return 0;
893 1052
1053err_add_device:
1054 hid_destroy_device(session->hid);
1055 session->hid = NULL;
1056 atomic_inc(&session->terminate);
1057 hidp_schedule(session);
1058
894unlink: 1059unlink:
895 hidp_del_timer(session); 1060 hidp_del_timer(session);
896 1061
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index 8d934a19da0a..13de5fa03480 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -80,6 +80,8 @@
80#define HIDP_VIRTUAL_CABLE_UNPLUG 0 80#define HIDP_VIRTUAL_CABLE_UNPLUG 0
81#define HIDP_BOOT_PROTOCOL_MODE 1 81#define HIDP_BOOT_PROTOCOL_MODE 1
82#define HIDP_BLUETOOTH_VENDOR_ID 9 82#define HIDP_BLUETOOTH_VENDOR_ID 9
83#define HIDP_WAITING_FOR_RETURN 10
84#define HIDP_WAITING_FOR_SEND_ACK 11
83 85
84struct hidp_connadd_req { 86struct hidp_connadd_req {
85 int ctrl_sock; // Connected control socket 87 int ctrl_sock; // Connected control socket
@@ -154,9 +156,22 @@ struct hidp_session {
154 struct sk_buff_head ctrl_transmit; 156 struct sk_buff_head ctrl_transmit;
155 struct sk_buff_head intr_transmit; 157 struct sk_buff_head intr_transmit;
156 158
159 /* Used in hidp_get_raw_report() */
160 int waiting_report_type; /* HIDP_DATA_RTYPE_* */
161 int waiting_report_number; /* -1 for not numbered */
162 struct mutex report_mutex;
163 struct sk_buff *report_return;
164 wait_queue_head_t report_queue;
165
166 /* Used in hidp_output_raw_report() */
167 int output_report_success; /* boolean */
168
157 /* Report descriptor */ 169 /* Report descriptor */
158 __u8 *rd_data; 170 __u8 *rd_data;
159 uint rd_size; 171 uint rd_size;
172
173 wait_queue_head_t startup_queue;
174 int waiting_for_startup;
160}; 175};
161 176
162static inline void hidp_schedule(struct hidp_session *session) 177static inline void hidp_schedule(struct hidp_session *session)
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
index 133fd22ea287..7b39f3ed2fda 100644
--- a/net/core/dev_addr_lists.c
+++ b/net/core/dev_addr_lists.c
@@ -357,8 +357,8 @@ EXPORT_SYMBOL(dev_addr_add_multiple);
357/** 357/**
358 * dev_addr_del_multiple - Delete device addresses by another device 358 * dev_addr_del_multiple - Delete device addresses by another device
359 * @to_dev: device where the addresses will be deleted 359 * @to_dev: device where the addresses will be deleted
360 * @from_dev: device by which addresses the addresses will be deleted 360 * @from_dev: device supplying the addresses to be deleted
361 * @addr_type: address type - 0 means type will used from from_dev 361 * @addr_type: address type - 0 means type will be used from from_dev
362 * 362 *
363 * Deletes addresses in to device by the list of addresses in from device. 363 * Deletes addresses in to device by the list of addresses in from device.
364 * 364 *
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 633a6c266136..b53197233709 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -124,7 +124,7 @@ out:
124} 124}
125EXPORT_SYMBOL(__inet6_lookup_established); 125EXPORT_SYMBOL(__inet6_lookup_established);
126 126
127static int inline compute_score(struct sock *sk, struct net *net, 127static inline int compute_score(struct sock *sk, struct net *net,
128 const unsigned short hnum, 128 const unsigned short hnum,
129 const struct in6_addr *daddr, 129 const struct in6_addr *daddr,
130 const int dif) 130 const int dif)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 081dcaf6577b..ce4596ed1268 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -169,7 +169,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
169 return cpu_to_le16(dur); 169 return cpu_to_le16(dur);
170} 170}
171 171
172static int inline is_ieee80211_device(struct ieee80211_local *local, 172static inline int is_ieee80211_device(struct ieee80211_local *local,
173 struct net_device *dev) 173 struct net_device *dev)
174{ 174{
175 return local == wdev_priv(dev->ieee80211_ptr); 175 return local == wdev_priv(dev->ieee80211_ptr);
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 45dbf1521b9a..f3914d0c5079 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -417,7 +417,7 @@ static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
417 gss_msg->msg.len += len; 417 gss_msg->msg.len += len;
418 } 418 }
419 if (mech->gm_upcall_enctypes) { 419 if (mech->gm_upcall_enctypes) {
420 len = sprintf(p, mech->gm_upcall_enctypes); 420 len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes);
421 p += len; 421 p += len;
422 gss_msg->msg.len += len; 422 gss_msg->msg.len += len;
423 } 423 }
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index f375decc024b..9022f0a6503e 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -750,7 +750,7 @@ static struct gss_api_mech gss_kerberos_mech = {
750 .gm_ops = &gss_kerberos_ops, 750 .gm_ops = &gss_kerberos_ops,
751 .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs), 751 .gm_pf_num = ARRAY_SIZE(gss_kerberos_pfs),
752 .gm_pfs = gss_kerberos_pfs, 752 .gm_pfs = gss_kerberos_pfs,
753 .gm_upcall_enctypes = "enctypes=18,17,16,23,3,1,2 ", 753 .gm_upcall_enctypes = "18,17,16,23,3,1,2",
754}; 754};
755 755
756static int __init init_kerberos_module(void) 756static int __init init_kerberos_module(void)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 57d344cf2256..e7a96e478f63 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -436,7 +436,9 @@ void rpc_killall_tasks(struct rpc_clnt *clnt)
436 if (!(rovr->tk_flags & RPC_TASK_KILLED)) { 436 if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
437 rovr->tk_flags |= RPC_TASK_KILLED; 437 rovr->tk_flags |= RPC_TASK_KILLED;
438 rpc_exit(rovr, -EIO); 438 rpc_exit(rovr, -EIO);
439 rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr); 439 if (RPC_IS_QUEUED(rovr))
440 rpc_wake_up_queued_task(rovr->tk_waitqueue,
441 rovr);
440 } 442 }
441 } 443 }
442 spin_unlock(&clnt->cl_lock); 444 spin_unlock(&clnt->cl_lock);
@@ -597,6 +599,14 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
597 } 599 }
598} 600}
599 601
602void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt)
603{
604 rpc_task_release_client(task);
605 rpc_task_set_client(task, clnt);
606}
607EXPORT_SYMBOL_GPL(rpc_task_reset_client);
608
609
600static void 610static void
601rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg) 611rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
602{ 612{
@@ -636,12 +646,6 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
636 rpc_task_set_client(task, task_setup_data->rpc_client); 646 rpc_task_set_client(task, task_setup_data->rpc_client);
637 rpc_task_set_rpc_message(task, task_setup_data->rpc_message); 647 rpc_task_set_rpc_message(task, task_setup_data->rpc_message);
638 648
639 if (task->tk_status != 0) {
640 int ret = task->tk_status;
641 rpc_put_task(task);
642 return ERR_PTR(ret);
643 }
644
645 if (task->tk_action == NULL) 649 if (task->tk_action == NULL)
646 rpc_call_start(task); 650 rpc_call_start(task);
647 651
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 3fc8624fcd17..ffb687671da0 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -299,15 +299,8 @@ static void rpc_make_runnable(struct rpc_task *task)
299 if (rpc_test_and_set_running(task)) 299 if (rpc_test_and_set_running(task))
300 return; 300 return;
301 if (RPC_IS_ASYNC(task)) { 301 if (RPC_IS_ASYNC(task)) {
302 int status;
303
304 INIT_WORK(&task->u.tk_work, rpc_async_schedule); 302 INIT_WORK(&task->u.tk_work, rpc_async_schedule);
305 status = queue_work(rpciod_workqueue, &task->u.tk_work); 303 queue_work(rpciod_workqueue, &task->u.tk_work);
306 if (status < 0) {
307 printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status);
308 task->tk_status = status;
309 return;
310 }
311 } else 304 } else
312 wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED); 305 wake_up_bit(&task->tk_runstate, RPC_TASK_QUEUED);
313} 306}
@@ -637,14 +630,12 @@ static void __rpc_execute(struct rpc_task *task)
637 save_callback = task->tk_callback; 630 save_callback = task->tk_callback;
638 task->tk_callback = NULL; 631 task->tk_callback = NULL;
639 save_callback(task); 632 save_callback(task);
640 } 633 } else {
641 634 /*
642 /* 635 * Perform the next FSM step.
643 * Perform the next FSM step. 636 * tk_action may be NULL when the task has been killed
644 * tk_action may be NULL when the task has been killed 637 * by someone else.
645 * by someone else. 638 */
646 */
647 if (!RPC_IS_QUEUED(task)) {
648 if (task->tk_action == NULL) 639 if (task->tk_action == NULL)
649 break; 640 break;
650 task->tk_action(task); 641 task->tk_action(task);
@@ -843,12 +834,6 @@ struct rpc_task *rpc_new_task(const struct rpc_task_setup *setup_data)
843 } 834 }
844 835
845 rpc_init_task(task, setup_data); 836 rpc_init_task(task, setup_data);
846 if (task->tk_status < 0) {
847 int err = task->tk_status;
848 rpc_put_task(task);
849 return ERR_PTR(err);
850 }
851
852 task->tk_flags |= flags; 837 task->tk_flags |= flags;
853 dprintk("RPC: allocated task %p\n", task); 838 dprintk("RPC: allocated task %p\n", task);
854 return task; 839 return task;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 856274d7e85c..9494c3767356 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -202,10 +202,9 @@ int xprt_reserve_xprt(struct rpc_task *task)
202 goto out_sleep; 202 goto out_sleep;
203 } 203 }
204 xprt->snd_task = task; 204 xprt->snd_task = task;
205 if (req) { 205 req->rq_bytes_sent = 0;
206 req->rq_bytes_sent = 0; 206 req->rq_ntrans++;
207 req->rq_ntrans++; 207
208 }
209 return 1; 208 return 1;
210 209
211out_sleep: 210out_sleep:
@@ -213,7 +212,7 @@ out_sleep:
213 task->tk_pid, xprt); 212 task->tk_pid, xprt);
214 task->tk_timeout = 0; 213 task->tk_timeout = 0;
215 task->tk_status = -EAGAIN; 214 task->tk_status = -EAGAIN;
216 if (req && req->rq_ntrans) 215 if (req->rq_ntrans)
217 rpc_sleep_on(&xprt->resend, task, NULL); 216 rpc_sleep_on(&xprt->resend, task, NULL);
218 else 217 else
219 rpc_sleep_on(&xprt->sending, task, NULL); 218 rpc_sleep_on(&xprt->sending, task, NULL);
@@ -965,7 +964,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req)
965 xprt = kzalloc(size, GFP_KERNEL); 964 xprt = kzalloc(size, GFP_KERNEL);
966 if (xprt == NULL) 965 if (xprt == NULL)
967 goto out; 966 goto out;
968 kref_init(&xprt->kref); 967 atomic_set(&xprt->count, 1);
969 968
970 xprt->max_reqs = max_req; 969 xprt->max_reqs = max_req;
971 xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); 970 xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL);
@@ -1145,13 +1144,11 @@ found:
1145 1144
1146/** 1145/**
1147 * xprt_destroy - destroy an RPC transport, killing off all requests. 1146 * xprt_destroy - destroy an RPC transport, killing off all requests.
1148 * @kref: kref for the transport to destroy 1147 * @xprt: transport to destroy
1149 * 1148 *
1150 */ 1149 */
1151static void xprt_destroy(struct kref *kref) 1150static void xprt_destroy(struct rpc_xprt *xprt)
1152{ 1151{
1153 struct rpc_xprt *xprt = container_of(kref, struct rpc_xprt, kref);
1154
1155 dprintk("RPC: destroying transport %p\n", xprt); 1152 dprintk("RPC: destroying transport %p\n", xprt);
1156 xprt->shutdown = 1; 1153 xprt->shutdown = 1;
1157 del_timer_sync(&xprt->timer); 1154 del_timer_sync(&xprt->timer);
@@ -1175,7 +1172,8 @@ static void xprt_destroy(struct kref *kref)
1175 */ 1172 */
1176void xprt_put(struct rpc_xprt *xprt) 1173void xprt_put(struct rpc_xprt *xprt)
1177{ 1174{
1178 kref_put(&xprt->kref, xprt_destroy); 1175 if (atomic_dec_and_test(&xprt->count))
1176 xprt_destroy(xprt);
1179} 1177}
1180 1178
1181/** 1179/**
@@ -1185,6 +1183,7 @@ void xprt_put(struct rpc_xprt *xprt)
1185 */ 1183 */
1186struct rpc_xprt *xprt_get(struct rpc_xprt *xprt) 1184struct rpc_xprt *xprt_get(struct rpc_xprt *xprt)
1187{ 1185{
1188 kref_get(&xprt->kref); 1186 if (atomic_inc_not_zero(&xprt->count))
1189 return xprt; 1187 return xprt;
1188 return NULL;
1190} 1189}
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 2ac3f6e8adff..554d0814c875 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -87,6 +87,8 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos,
87 enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg, int nsegs) 87 enum rpcrdma_chunktype type, struct rpcrdma_mr_seg *seg, int nsegs)
88{ 88{
89 int len, n = 0, p; 89 int len, n = 0, p;
90 int page_base;
91 struct page **ppages;
90 92
91 if (pos == 0 && xdrbuf->head[0].iov_len) { 93 if (pos == 0 && xdrbuf->head[0].iov_len) {
92 seg[n].mr_page = NULL; 94 seg[n].mr_page = NULL;
@@ -95,34 +97,32 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos,
95 ++n; 97 ++n;
96 } 98 }
97 99
98 if (xdrbuf->page_len && (xdrbuf->pages[0] != NULL)) { 100 len = xdrbuf->page_len;
99 if (n == nsegs) 101 ppages = xdrbuf->pages + (xdrbuf->page_base >> PAGE_SHIFT);
100 return 0; 102 page_base = xdrbuf->page_base & ~PAGE_MASK;
101 seg[n].mr_page = xdrbuf->pages[0]; 103 p = 0;
102 seg[n].mr_offset = (void *)(unsigned long) xdrbuf->page_base; 104 while (len && n < nsegs) {
103 seg[n].mr_len = min_t(u32, 105 seg[n].mr_page = ppages[p];
104 PAGE_SIZE - xdrbuf->page_base, xdrbuf->page_len); 106 seg[n].mr_offset = (void *)(unsigned long) page_base;
105 len = xdrbuf->page_len - seg[n].mr_len; 107 seg[n].mr_len = min_t(u32, PAGE_SIZE - page_base, len);
108 BUG_ON(seg[n].mr_len > PAGE_SIZE);
109 len -= seg[n].mr_len;
106 ++n; 110 ++n;
107 p = 1; 111 ++p;
108 while (len > 0) { 112 page_base = 0; /* page offset only applies to first page */
109 if (n == nsegs)
110 return 0;
111 seg[n].mr_page = xdrbuf->pages[p];
112 seg[n].mr_offset = NULL;
113 seg[n].mr_len = min_t(u32, PAGE_SIZE, len);
114 len -= seg[n].mr_len;
115 ++n;
116 ++p;
117 }
118 } 113 }
119 114
115 /* Message overflows the seg array */
116 if (len && n == nsegs)
117 return 0;
118
120 if (xdrbuf->tail[0].iov_len) { 119 if (xdrbuf->tail[0].iov_len) {
121 /* the rpcrdma protocol allows us to omit any trailing 120 /* the rpcrdma protocol allows us to omit any trailing
122 * xdr pad bytes, saving the server an RDMA operation. */ 121 * xdr pad bytes, saving the server an RDMA operation. */
123 if (xdrbuf->tail[0].iov_len < 4 && xprt_rdma_pad_optimize) 122 if (xdrbuf->tail[0].iov_len < 4 && xprt_rdma_pad_optimize)
124 return n; 123 return n;
125 if (n == nsegs) 124 if (n == nsegs)
125 /* Tail remains, but we're out of segments */
126 return 0; 126 return 0;
127 seg[n].mr_page = NULL; 127 seg[n].mr_page = NULL;
128 seg[n].mr_offset = xdrbuf->tail[0].iov_base; 128 seg[n].mr_offset = xdrbuf->tail[0].iov_base;
@@ -296,6 +296,8 @@ rpcrdma_inline_pullup(struct rpc_rqst *rqst, int pad)
296 int copy_len; 296 int copy_len;
297 unsigned char *srcp, *destp; 297 unsigned char *srcp, *destp;
298 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt); 298 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(rqst->rq_xprt);
299 int page_base;
300 struct page **ppages;
299 301
300 destp = rqst->rq_svec[0].iov_base; 302 destp = rqst->rq_svec[0].iov_base;
301 curlen = rqst->rq_svec[0].iov_len; 303 curlen = rqst->rq_svec[0].iov_len;
@@ -324,28 +326,25 @@ rpcrdma_inline_pullup(struct rpc_rqst *rqst, int pad)
324 __func__, destp + copy_len, curlen); 326 __func__, destp + copy_len, curlen);
325 rqst->rq_svec[0].iov_len += curlen; 327 rqst->rq_svec[0].iov_len += curlen;
326 } 328 }
327
328 r_xprt->rx_stats.pullup_copy_count += copy_len; 329 r_xprt->rx_stats.pullup_copy_count += copy_len;
329 npages = PAGE_ALIGN(rqst->rq_snd_buf.page_base+copy_len) >> PAGE_SHIFT; 330
331 page_base = rqst->rq_snd_buf.page_base;
332 ppages = rqst->rq_snd_buf.pages + (page_base >> PAGE_SHIFT);
333 page_base &= ~PAGE_MASK;
334 npages = PAGE_ALIGN(page_base+copy_len) >> PAGE_SHIFT;
330 for (i = 0; copy_len && i < npages; i++) { 335 for (i = 0; copy_len && i < npages; i++) {
331 if (i == 0) 336 curlen = PAGE_SIZE - page_base;
332 curlen = PAGE_SIZE - rqst->rq_snd_buf.page_base;
333 else
334 curlen = PAGE_SIZE;
335 if (curlen > copy_len) 337 if (curlen > copy_len)
336 curlen = copy_len; 338 curlen = copy_len;
337 dprintk("RPC: %s: page %d destp 0x%p len %d curlen %d\n", 339 dprintk("RPC: %s: page %d destp 0x%p len %d curlen %d\n",
338 __func__, i, destp, copy_len, curlen); 340 __func__, i, destp, copy_len, curlen);
339 srcp = kmap_atomic(rqst->rq_snd_buf.pages[i], 341 srcp = kmap_atomic(ppages[i], KM_SKB_SUNRPC_DATA);
340 KM_SKB_SUNRPC_DATA); 342 memcpy(destp, srcp+page_base, curlen);
341 if (i == 0)
342 memcpy(destp, srcp+rqst->rq_snd_buf.page_base, curlen);
343 else
344 memcpy(destp, srcp, curlen);
345 kunmap_atomic(srcp, KM_SKB_SUNRPC_DATA); 343 kunmap_atomic(srcp, KM_SKB_SUNRPC_DATA);
346 rqst->rq_svec[0].iov_len += curlen; 344 rqst->rq_svec[0].iov_len += curlen;
347 destp += curlen; 345 destp += curlen;
348 copy_len -= curlen; 346 copy_len -= curlen;
347 page_base = 0;
349 } 348 }
350 /* header now contains entire send message */ 349 /* header now contains entire send message */
351 return pad; 350 return pad;
@@ -606,6 +605,8 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
606{ 605{
607 int i, npages, curlen, olen; 606 int i, npages, curlen, olen;
608 char *destp; 607 char *destp;
608 struct page **ppages;
609 int page_base;
609 610
610 curlen = rqst->rq_rcv_buf.head[0].iov_len; 611 curlen = rqst->rq_rcv_buf.head[0].iov_len;
611 if (curlen > copy_len) { /* write chunk header fixup */ 612 if (curlen > copy_len) { /* write chunk header fixup */
@@ -624,32 +625,29 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
624 olen = copy_len; 625 olen = copy_len;
625 i = 0; 626 i = 0;
626 rpcx_to_rdmax(rqst->rq_xprt)->rx_stats.fixup_copy_count += olen; 627 rpcx_to_rdmax(rqst->rq_xprt)->rx_stats.fixup_copy_count += olen;
628 page_base = rqst->rq_rcv_buf.page_base;
629 ppages = rqst->rq_rcv_buf.pages + (page_base >> PAGE_SHIFT);
630 page_base &= ~PAGE_MASK;
631
627 if (copy_len && rqst->rq_rcv_buf.page_len) { 632 if (copy_len && rqst->rq_rcv_buf.page_len) {
628 npages = PAGE_ALIGN(rqst->rq_rcv_buf.page_base + 633 npages = PAGE_ALIGN(page_base +
629 rqst->rq_rcv_buf.page_len) >> PAGE_SHIFT; 634 rqst->rq_rcv_buf.page_len) >> PAGE_SHIFT;
630 for (; i < npages; i++) { 635 for (; i < npages; i++) {
631 if (i == 0) 636 curlen = PAGE_SIZE - page_base;
632 curlen = PAGE_SIZE - rqst->rq_rcv_buf.page_base;
633 else
634 curlen = PAGE_SIZE;
635 if (curlen > copy_len) 637 if (curlen > copy_len)
636 curlen = copy_len; 638 curlen = copy_len;
637 dprintk("RPC: %s: page %d" 639 dprintk("RPC: %s: page %d"
638 " srcp 0x%p len %d curlen %d\n", 640 " srcp 0x%p len %d curlen %d\n",
639 __func__, i, srcp, copy_len, curlen); 641 __func__, i, srcp, copy_len, curlen);
640 destp = kmap_atomic(rqst->rq_rcv_buf.pages[i], 642 destp = kmap_atomic(ppages[i], KM_SKB_SUNRPC_DATA);
641 KM_SKB_SUNRPC_DATA); 643 memcpy(destp + page_base, srcp, curlen);
642 if (i == 0) 644 flush_dcache_page(ppages[i]);
643 memcpy(destp + rqst->rq_rcv_buf.page_base,
644 srcp, curlen);
645 else
646 memcpy(destp, srcp, curlen);
647 flush_dcache_page(rqst->rq_rcv_buf.pages[i]);
648 kunmap_atomic(destp, KM_SKB_SUNRPC_DATA); 645 kunmap_atomic(destp, KM_SKB_SUNRPC_DATA);
649 srcp += curlen; 646 srcp += curlen;
650 copy_len -= curlen; 647 copy_len -= curlen;
651 if (copy_len == 0) 648 if (copy_len == 0)
652 break; 649 break;
650 page_base = 0;
653 } 651 }
654 rqst->rq_rcv_buf.page_len = olen - copy_len; 652 rqst->rq_rcv_buf.page_len = olen - copy_len;
655 } else 653 } else
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 5f4c7b3bc711..d4297dc43dc4 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -144,6 +144,7 @@ rpcrdma_cq_async_error_upcall(struct ib_event *event, void *context)
144static inline 144static inline
145void rpcrdma_event_process(struct ib_wc *wc) 145void rpcrdma_event_process(struct ib_wc *wc)
146{ 146{
147 struct rpcrdma_mw *frmr;
147 struct rpcrdma_rep *rep = 148 struct rpcrdma_rep *rep =
148 (struct rpcrdma_rep *)(unsigned long) wc->wr_id; 149 (struct rpcrdma_rep *)(unsigned long) wc->wr_id;
149 150
@@ -154,15 +155,23 @@ void rpcrdma_event_process(struct ib_wc *wc)
154 return; 155 return;
155 156
156 if (IB_WC_SUCCESS != wc->status) { 157 if (IB_WC_SUCCESS != wc->status) {
157 dprintk("RPC: %s: %s WC status %X, connection lost\n", 158 dprintk("RPC: %s: WC opcode %d status %X, connection lost\n",
158 __func__, (wc->opcode & IB_WC_RECV) ? "recv" : "send", 159 __func__, wc->opcode, wc->status);
159 wc->status);
160 rep->rr_len = ~0U; 160 rep->rr_len = ~0U;
161 rpcrdma_schedule_tasklet(rep); 161 if (wc->opcode != IB_WC_FAST_REG_MR && wc->opcode != IB_WC_LOCAL_INV)
162 rpcrdma_schedule_tasklet(rep);
162 return; 163 return;
163 } 164 }
164 165
165 switch (wc->opcode) { 166 switch (wc->opcode) {
167 case IB_WC_FAST_REG_MR:
168 frmr = (struct rpcrdma_mw *)(unsigned long)wc->wr_id;
169 frmr->r.frmr.state = FRMR_IS_VALID;
170 break;
171 case IB_WC_LOCAL_INV:
172 frmr = (struct rpcrdma_mw *)(unsigned long)wc->wr_id;
173 frmr->r.frmr.state = FRMR_IS_INVALID;
174 break;
166 case IB_WC_RECV: 175 case IB_WC_RECV:
167 rep->rr_len = wc->byte_len; 176 rep->rr_len = wc->byte_len;
168 ib_dma_sync_single_for_cpu( 177 ib_dma_sync_single_for_cpu(
@@ -1450,6 +1459,12 @@ rpcrdma_map_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg, int writing)
1450 seg->mr_dma = ib_dma_map_single(ia->ri_id->device, 1459 seg->mr_dma = ib_dma_map_single(ia->ri_id->device,
1451 seg->mr_offset, 1460 seg->mr_offset,
1452 seg->mr_dmalen, seg->mr_dir); 1461 seg->mr_dmalen, seg->mr_dir);
1462 if (ib_dma_mapping_error(ia->ri_id->device, seg->mr_dma)) {
1463 dprintk("RPC: %s: mr_dma %llx mr_offset %p mr_dma_len %zu\n",
1464 __func__,
1465 (unsigned long long)seg->mr_dma,
1466 seg->mr_offset, seg->mr_dmalen);
1467 }
1453} 1468}
1454 1469
1455static void 1470static void
@@ -1469,7 +1484,8 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1469 struct rpcrdma_xprt *r_xprt) 1484 struct rpcrdma_xprt *r_xprt)
1470{ 1485{
1471 struct rpcrdma_mr_seg *seg1 = seg; 1486 struct rpcrdma_mr_seg *seg1 = seg;
1472 struct ib_send_wr frmr_wr, *bad_wr; 1487 struct ib_send_wr invalidate_wr, frmr_wr, *bad_wr, *post_wr;
1488
1473 u8 key; 1489 u8 key;
1474 int len, pageoff; 1490 int len, pageoff;
1475 int i, rc; 1491 int i, rc;
@@ -1484,6 +1500,7 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1484 rpcrdma_map_one(ia, seg, writing); 1500 rpcrdma_map_one(ia, seg, writing);
1485 seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->page_list[i] = seg->mr_dma; 1501 seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->page_list[i] = seg->mr_dma;
1486 len += seg->mr_len; 1502 len += seg->mr_len;
1503 BUG_ON(seg->mr_len > PAGE_SIZE);
1487 ++seg; 1504 ++seg;
1488 ++i; 1505 ++i;
1489 /* Check for holes */ 1506 /* Check for holes */
@@ -1494,26 +1511,45 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1494 dprintk("RPC: %s: Using frmr %p to map %d segments\n", 1511 dprintk("RPC: %s: Using frmr %p to map %d segments\n",
1495 __func__, seg1->mr_chunk.rl_mw, i); 1512 __func__, seg1->mr_chunk.rl_mw, i);
1496 1513
1514 if (unlikely(seg1->mr_chunk.rl_mw->r.frmr.state == FRMR_IS_VALID)) {
1515 dprintk("RPC: %s: frmr %x left valid, posting invalidate.\n",
1516 __func__,
1517 seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey);
1518 /* Invalidate before using. */
1519 memset(&invalidate_wr, 0, sizeof invalidate_wr);
1520 invalidate_wr.wr_id = (unsigned long)(void *)seg1->mr_chunk.rl_mw;
1521 invalidate_wr.next = &frmr_wr;
1522 invalidate_wr.opcode = IB_WR_LOCAL_INV;
1523 invalidate_wr.send_flags = IB_SEND_SIGNALED;
1524 invalidate_wr.ex.invalidate_rkey =
1525 seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
1526 DECR_CQCOUNT(&r_xprt->rx_ep);
1527 post_wr = &invalidate_wr;
1528 } else
1529 post_wr = &frmr_wr;
1530
1497 /* Bump the key */ 1531 /* Bump the key */
1498 key = (u8)(seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey & 0x000000FF); 1532 key = (u8)(seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey & 0x000000FF);
1499 ib_update_fast_reg_key(seg1->mr_chunk.rl_mw->r.frmr.fr_mr, ++key); 1533 ib_update_fast_reg_key(seg1->mr_chunk.rl_mw->r.frmr.fr_mr, ++key);
1500 1534
1501 /* Prepare FRMR WR */ 1535 /* Prepare FRMR WR */
1502 memset(&frmr_wr, 0, sizeof frmr_wr); 1536 memset(&frmr_wr, 0, sizeof frmr_wr);
1537 frmr_wr.wr_id = (unsigned long)(void *)seg1->mr_chunk.rl_mw;
1503 frmr_wr.opcode = IB_WR_FAST_REG_MR; 1538 frmr_wr.opcode = IB_WR_FAST_REG_MR;
1504 frmr_wr.send_flags = 0; /* unsignaled */ 1539 frmr_wr.send_flags = IB_SEND_SIGNALED;
1505 frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma; 1540 frmr_wr.wr.fast_reg.iova_start = seg1->mr_dma;
1506 frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl; 1541 frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
1507 frmr_wr.wr.fast_reg.page_list_len = i; 1542 frmr_wr.wr.fast_reg.page_list_len = i;
1508 frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT; 1543 frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
1509 frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT; 1544 frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT;
1545 BUG_ON(frmr_wr.wr.fast_reg.length < len);
1510 frmr_wr.wr.fast_reg.access_flags = (writing ? 1546 frmr_wr.wr.fast_reg.access_flags = (writing ?
1511 IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE : 1547 IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :
1512 IB_ACCESS_REMOTE_READ); 1548 IB_ACCESS_REMOTE_READ);
1513 frmr_wr.wr.fast_reg.rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey; 1549 frmr_wr.wr.fast_reg.rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
1514 DECR_CQCOUNT(&r_xprt->rx_ep); 1550 DECR_CQCOUNT(&r_xprt->rx_ep);
1515 1551
1516 rc = ib_post_send(ia->ri_id->qp, &frmr_wr, &bad_wr); 1552 rc = ib_post_send(ia->ri_id->qp, post_wr, &bad_wr);
1517 1553
1518 if (rc) { 1554 if (rc) {
1519 dprintk("RPC: %s: failed ib_post_send for register," 1555 dprintk("RPC: %s: failed ib_post_send for register,"
@@ -1542,8 +1578,9 @@ rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg,
1542 rpcrdma_unmap_one(ia, seg++); 1578 rpcrdma_unmap_one(ia, seg++);
1543 1579
1544 memset(&invalidate_wr, 0, sizeof invalidate_wr); 1580 memset(&invalidate_wr, 0, sizeof invalidate_wr);
1581 invalidate_wr.wr_id = (unsigned long)(void *)seg1->mr_chunk.rl_mw;
1545 invalidate_wr.opcode = IB_WR_LOCAL_INV; 1582 invalidate_wr.opcode = IB_WR_LOCAL_INV;
1546 invalidate_wr.send_flags = 0; /* unsignaled */ 1583 invalidate_wr.send_flags = IB_SEND_SIGNALED;
1547 invalidate_wr.ex.invalidate_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey; 1584 invalidate_wr.ex.invalidate_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
1548 DECR_CQCOUNT(&r_xprt->rx_ep); 1585 DECR_CQCOUNT(&r_xprt->rx_ep);
1549 1586
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index c7a7eba991bc..cae761a8536c 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -164,6 +164,7 @@ struct rpcrdma_mr_seg { /* chunk descriptors */
164 struct { 164 struct {
165 struct ib_fast_reg_page_list *fr_pgl; 165 struct ib_fast_reg_page_list *fr_pgl;
166 struct ib_mr *fr_mr; 166 struct ib_mr *fr_mr;
167 enum { FRMR_IS_INVALID, FRMR_IS_VALID } state;
167 } frmr; 168 } frmr;
168 } r; 169 } r;
169 struct list_head mw_list; 170 struct list_head mw_list;