Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/srp: Implement SRP_CRED_REQ and SRP_AER_REQ

This patch adds support for SRP_CRED_REQ to avoid a lockup by targets
that use that mechanism to return credits to the initiator. This
prevents a lockup observed in the field where we would never add the
credits from the SRP_CRED_REQ to our current count, and would therefore
never send another command to the target.

Minimal support for SRP_AER_REQ is also added, as these messages can
also be used to convey additional credits to the initiator.

Based upon extensive debugging and code by Bart Van Assche and a bug
report by Chris Worley.

Signed-off-by: David Dillow <dillowda@ornl.gov>
Signed-off-by: Roland Dreier <rolandd@cisco.com>

authored by

David Dillow and committed by
Roland Dreier
bb12588a dd5e6e38

+141 -10
+98 -7
drivers/infiniband/ulp/srp/ib_srp.c
··· 83 83 static void srp_recv_completion(struct ib_cq *cq, void *target_ptr); 84 84 static void srp_send_completion(struct ib_cq *cq, void *target_ptr); 85 85 static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); 86 + static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, 87 + enum srp_iu_type iu_type); 88 + static int __srp_post_send(struct srp_target_port *target, 89 + struct srp_iu *iu, int len); 86 90 87 91 static struct scsi_transport_template *ib_srp_transport_template; 88 92 ··· 900 896 spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 901 897 } 902 898 899 + static int srp_response_common(struct srp_target_port *target, s32 req_delta, 900 + void *rsp, int len) 901 + { 902 + struct ib_device *dev; 903 + unsigned long flags; 904 + struct srp_iu *iu; 905 + int err = 1; 906 + 907 + dev = target->srp_host->srp_dev->dev; 908 + 909 + spin_lock_irqsave(target->scsi_host->host_lock, flags); 910 + target->req_lim += req_delta; 911 + 912 + iu = __srp_get_tx_iu(target, SRP_IU_RSP); 913 + if (!iu) { 914 + shost_printk(KERN_ERR, target->scsi_host, PFX 915 + "no IU available to send response\n"); 916 + goto out; 917 + } 918 + 919 + ib_dma_sync_single_for_cpu(dev, iu->dma, len, DMA_TO_DEVICE); 920 + memcpy(iu->buf, rsp, len); 921 + ib_dma_sync_single_for_device(dev, iu->dma, len, DMA_TO_DEVICE); 922 + 923 + err = __srp_post_send(target, iu, len); 924 + if (err) 925 + shost_printk(KERN_ERR, target->scsi_host, PFX 926 + "unable to post response: %d\n", err); 927 + 928 + out: 929 + spin_unlock_irqrestore(target->scsi_host->host_lock, flags); 930 + return err; 931 + } 932 + 933 + static void srp_process_cred_req(struct srp_target_port *target, 934 + struct srp_cred_req *req) 935 + { 936 + struct srp_cred_rsp rsp = { 937 + .opcode = SRP_CRED_RSP, 938 + .tag = req->tag, 939 + }; 940 + s32 delta = be32_to_cpu(req->req_lim_delta); 941 + 942 + if (srp_response_common(target, delta, &rsp, sizeof rsp)) 943 + shost_printk(KERN_ERR, target->scsi_host, PFX 944 + "problems processing SRP_CRED_REQ\n"); 945 + } 946 + 947 + static void srp_process_aer_req(struct srp_target_port *target, 948 + struct srp_aer_req *req) 949 + { 950 + struct srp_aer_rsp rsp = { 951 + .opcode = SRP_AER_RSP, 952 + .tag = req->tag, 953 + }; 954 + s32 delta = be32_to_cpu(req->req_lim_delta); 955 + 956 + shost_printk(KERN_ERR, target->scsi_host, PFX 957 + "ignoring AER for LUN %llu\n", be64_to_cpu(req->lun)); 958 + 959 + if (srp_response_common(target, delta, &rsp, sizeof rsp)) 960 + shost_printk(KERN_ERR, target->scsi_host, PFX 961 + "problems processing SRP_AER_REQ\n"); 962 + } 963 + 903 964 static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) 904 965 { 905 966 struct ib_device *dev; ··· 990 921 switch (opcode) { 991 922 case SRP_RSP: 992 923 srp_process_rsp(target, iu->buf); 924 + break; 925 + 926 + case SRP_CRED_REQ: 927 + srp_process_cred_req(target, iu->buf); 928 + break; 929 + 930 + case SRP_AER_REQ: 931 + srp_process_aer_req(target, iu->buf); 993 932 break; 994 933 995 934 case SRP_T_LOGOUT: ··· 1062 985 * Must be called with target->scsi_host->host_lock held to protect 1063 986 * req_lim and tx_head. Lock cannot be dropped between call here and 1064 987 * call to __srp_post_send(). 988 + * 989 + * Note: 990 + * An upper limit for the number of allocated information units for each 991 + * request type is: 992 + * - SRP_IU_CMD: SRP_CMD_SQ_SIZE, since the SCSI mid-layer never queues 993 + * more than Scsi_Host.can_queue requests. 994 + * - SRP_IU_TSK_MGMT: SRP_TSK_MGMT_SQ_SIZE. 995 + * - SRP_IU_RSP: 1, since a conforming SRP target never sends more than 996 + * one unanswered SRP request to an initiator. 1065 997 */ 1066 998 static struct srp_iu *__srp_get_tx_iu(struct srp_target_port *target, 1067 - enum srp_request_type req_type) 999 + enum srp_iu_type iu_type) 1068 1000 { 1069 - s32 rsv = (req_type == SRP_REQ_TASK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; 1001 + s32 rsv = (iu_type == SRP_IU_TSK_MGMT) ? 0 : SRP_TSK_MGMT_SQ_SIZE; 1002 + struct srp_iu *iu; 1070 1003 1071 1004 srp_send_completion(target->send_cq, target); 1072 1005 1073 1006 if (target->tx_head - target->tx_tail >= SRP_SQ_SIZE) 1074 1007 return NULL; 1075 1008 1076 - if (target->req_lim <= rsv) { 1009 + /* Initiator responses to target requests do not consume credits */ 1010 + if (target->req_lim <= rsv && iu_type != SRP_IU_RSP) { 1077 1011 ++target->zero_req_lim; 1078 1012 return NULL; 1079 1013 } 1080 1014 1081 - return target->tx_ring[target->tx_head & SRP_SQ_MASK]; 1015 + iu = target->tx_ring[target->tx_head & SRP_SQ_MASK]; 1016 + iu->type = iu_type; 1017 + return iu; 1082 1018 } 1083 1019 1084 1020 /* ··· 1120 1030 1121 1031 if (!ret) { 1122 1032 ++target->tx_head; 1123 - --target->req_lim; 1033 + if (iu->type != SRP_IU_RSP) 1034 + --target->req_lim; 1124 1035 } 1125 1036 1126 1037 return ret; ··· 1147 1056 return 0; 1148 1057 } 1149 1058 1150 - iu = __srp_get_tx_iu(target, SRP_REQ_NORMAL); 1059 + iu = __srp_get_tx_iu(target, SRP_IU_CMD); 1151 1060 if (!iu) 1152 1061 goto err; 1153 1062 ··· 1454 1363 1455 1364 init_completion(&req->done); 1456 1365 1457 - iu = __srp_get_tx_iu(target, SRP_REQ_TASK_MGMT); 1366 + iu = __srp_get_tx_iu(target, SRP_IU_TSK_MGMT); 1458 1367 if (!iu) 1459 1368 goto out; 1460 1369
+5 -3
drivers/infiniband/ulp/srp/ib_srp.h
··· 82 82 SRP_TARGET_REMOVED 83 83 }; 84 84 85 - enum srp_request_type { 86 - SRP_REQ_NORMAL, 87 - SRP_REQ_TASK_MGMT, 85 + enum srp_iu_type { 86 + SRP_IU_CMD, 87 + SRP_IU_TSK_MGMT, 88 + SRP_IU_RSP, 88 89 }; 89 90 90 91 struct srp_device { ··· 172 171 void *buf; 173 172 size_t size; 174 173 enum dma_data_direction direction; 174 + enum srp_iu_type type; 175 175 }; 176 176 177 177 #endif /* IB_SRP_H */
+38
include/scsi/srp.h
··· 239 239 u8 data[0]; 240 240 } __attribute__((packed)); 241 241 242 + struct srp_cred_req { 243 + u8 opcode; 244 + u8 sol_not; 245 + u8 reserved[2]; 246 + __be32 req_lim_delta; 247 + u64 tag; 248 + }; 249 + 250 + struct srp_cred_rsp { 251 + u8 opcode; 252 + u8 reserved[7]; 253 + u64 tag; 254 + }; 255 + 256 + /* 257 + * The SRP spec defines the fixed portion of the AER_REQ structure to be 258 + * 36 bytes, so it needs to be packed to avoid having it padded to 40 bytes 259 + * on 64-bit architectures. 260 + */ 261 + struct srp_aer_req { 262 + u8 opcode; 263 + u8 sol_not; 264 + u8 reserved[2]; 265 + __be32 req_lim_delta; 266 + u64 tag; 267 + u32 reserved2; 268 + __be64 lun; 269 + __be32 sense_data_len; 270 + u32 reserved3; 271 + u8 sense_data[0]; 272 + } __attribute__((packed)); 273 + 274 + struct srp_aer_rsp { 275 + u8 opcode; 276 + u8 reserved[7]; 277 + u64 tag; 278 + }; 279 + 242 280 #endif /* SCSI_SRP_H */