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

scsi: storvsc: Use blk_mq_unique_tag() to generate requestIDs

Use blk_mq_unique_tag() to generate requestIDs for StorVSC, avoiding
all issues with allocating enough entries in the VMbus requestor.

Suggested-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Andrea Parri (Microsoft) <parri.andrea@gmail.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
Link: https://lore.kernel.org/r/20210510210841.370472-1-parri.andrea@gmail.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>

authored by

Andrea Parri (Microsoft) and committed by
Wei Liu
bf5fd8ca adae1e93

+95 -49
+6 -8
drivers/hv/channel.c
··· 1189 1189 * vmbus_next_request_id - Returns a new request id. It is also 1190 1190 * the index at which the guest memory address is stored. 1191 1191 * Uses a spin lock to avoid race conditions. 1192 - * @rqstor: Pointer to the requestor struct 1192 + * @channel: Pointer to the VMbus channel struct 1193 1193 * @rqst_add: Guest memory address to be stored in the array 1194 1194 */ 1195 - u64 vmbus_next_request_id(struct vmbus_requestor *rqstor, u64 rqst_addr) 1195 + u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) 1196 1196 { 1197 + struct vmbus_requestor *rqstor = &channel->requestor; 1197 1198 unsigned long flags; 1198 1199 u64 current_id; 1199 - const struct vmbus_channel *channel = 1200 - container_of(rqstor, const struct vmbus_channel, requestor); 1201 1200 1202 1201 /* Check rqstor has been initialized */ 1203 1202 if (!channel->rqstor_size) ··· 1230 1231 /* 1231 1232 * vmbus_request_addr - Returns the memory address stored at @trans_id 1232 1233 * in @rqstor. Uses a spin lock to avoid race conditions. 1233 - * @rqstor: Pointer to the requestor struct 1234 + * @channel: Pointer to the VMbus channel struct 1234 1235 * @trans_id: Request id sent back from Hyper-V. Becomes the requestor's 1235 1236 * next request id. 1236 1237 */ 1237 - u64 vmbus_request_addr(struct vmbus_requestor *rqstor, u64 trans_id) 1238 + u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id) 1238 1239 { 1240 + struct vmbus_requestor *rqstor = &channel->requestor; 1239 1241 unsigned long flags; 1240 1242 u64 req_addr; 1241 - const struct vmbus_channel *channel = 1242 - container_of(rqstor, const struct vmbus_channel, requestor); 1243 1243 1244 1244 /* Check rqstor has been initialized */ 1245 1245 if (!channel->rqstor_size)
+8 -5
drivers/hv/ring_buffer.c
··· 312 312 */ 313 313 314 314 if (desc->flags == VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED) { 315 - rqst_id = vmbus_next_request_id(&channel->requestor, requestid); 316 - if (rqst_id == VMBUS_RQST_ERROR) { 317 - spin_unlock_irqrestore(&outring_info->ring_lock, flags); 318 - return -EAGAIN; 315 + if (channel->next_request_id_callback != NULL) { 316 + rqst_id = channel->next_request_id_callback(channel, requestid); 317 + if (rqst_id == VMBUS_RQST_ERROR) { 318 + spin_unlock_irqrestore(&outring_info->ring_lock, flags); 319 + return -EAGAIN; 320 + } 319 321 } 320 322 } 321 323 desc = hv_get_ring_buffer(outring_info) + old_write; ··· 345 343 if (channel->rescind) { 346 344 if (rqst_id != VMBUS_NO_RQSTOR) { 347 345 /* Reclaim request ID to avoid leak of IDs */ 348 - vmbus_request_addr(&channel->requestor, rqst_id); 346 + if (channel->request_addr_callback != NULL) 347 + channel->request_addr_callback(channel, rqst_id); 349 348 } 350 349 return -ENODEV; 351 350 }
+5 -3
drivers/net/hyperv/netvsc.c
··· 757 757 int queue_sends; 758 758 u64 cmd_rqst; 759 759 760 - cmd_rqst = vmbus_request_addr(&channel->requestor, (u64)desc->trans_id); 760 + cmd_rqst = channel->request_addr_callback(channel, (u64)desc->trans_id); 761 761 if (cmd_rqst == VMBUS_RQST_ERROR) { 762 762 netdev_err(ndev, "Incorrect transaction id\n"); 763 763 return; ··· 817 817 818 818 /* First check if this is a VMBUS completion without data payload */ 819 819 if (!msglen) { 820 - cmd_rqst = vmbus_request_addr(&incoming_channel->requestor, 821 - (u64)desc->trans_id); 820 + cmd_rqst = incoming_channel->request_addr_callback(incoming_channel, 821 + (u64)desc->trans_id); 822 822 if (cmd_rqst == VMBUS_RQST_ERROR) { 823 823 netdev_err(ndev, "Invalid transaction id\n"); 824 824 return; ··· 1649 1649 netvsc_poll, NAPI_POLL_WEIGHT); 1650 1650 1651 1651 /* Open the channel */ 1652 + device->channel->next_request_id_callback = vmbus_next_request_id; 1653 + device->channel->request_addr_callback = vmbus_request_addr; 1652 1654 device->channel->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes); 1653 1655 device->channel->max_pkt_size = NETVSC_MAX_PKT_SIZE; 1654 1656
+2
drivers/net/hyperv/rndis_filter.c
··· 1259 1259 /* Set the channel before opening.*/ 1260 1260 nvchan->channel = new_sc; 1261 1261 1262 + new_sc->next_request_id_callback = vmbus_next_request_id; 1263 + new_sc->request_addr_callback = vmbus_request_addr; 1262 1264 new_sc->rqstor_size = netvsc_rqstor_size(netvsc_ring_bytes); 1263 1265 new_sc->max_pkt_size = NETVSC_MAX_PKT_SIZE; 1264 1266
+63 -31
drivers/scsi/storvsc_drv.c
··· 696 696 spin_unlock_irqrestore(&stor_device->lock, flags); 697 697 } 698 698 699 + static u64 storvsc_next_request_id(struct vmbus_channel *channel, u64 rqst_addr) 700 + { 701 + struct storvsc_cmd_request *request = 702 + (struct storvsc_cmd_request *)(unsigned long)rqst_addr; 703 + 704 + if (rqst_addr == VMBUS_RQST_INIT) 705 + return VMBUS_RQST_INIT; 706 + if (rqst_addr == VMBUS_RQST_RESET) 707 + return VMBUS_RQST_RESET; 708 + 709 + /* 710 + * Cannot return an ID of 0, which is reserved for an unsolicited 711 + * message from Hyper-V. 712 + */ 713 + return (u64)blk_mq_unique_tag(request->cmd->request) + 1; 714 + } 715 + 699 716 static void handle_sc_creation(struct vmbus_channel *new_sc) 700 717 { 701 718 struct hv_device *device = new_sc->primary_channel->device_obj; ··· 728 711 memset(&props, 0, sizeof(struct vmstorage_channel_properties)); 729 712 new_sc->max_pkt_size = STORVSC_MAX_PKT_SIZE; 730 713 731 - /* 732 - * The size of vmbus_requestor is an upper bound on the number of requests 733 - * that can be in-progress at any one time across all channels. 734 - */ 735 - new_sc->rqstor_size = scsi_driver.can_queue; 714 + new_sc->next_request_id_callback = storvsc_next_request_id; 736 715 737 716 ret = vmbus_open(new_sc, 738 717 storvsc_ringbuffer_size, ··· 795 782 ret = vmbus_sendpacket(device->channel, vstor_packet, 796 783 (sizeof(struct vstor_packet) - 797 784 stor_device->vmscsi_size_delta), 798 - (unsigned long)request, 785 + VMBUS_RQST_INIT, 799 786 VM_PKT_DATA_INBAND, 800 787 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 801 788 ··· 864 851 ret = vmbus_sendpacket(device->channel, vstor_packet, 865 852 (sizeof(struct vstor_packet) - 866 853 stor_device->vmscsi_size_delta), 867 - (unsigned long)request, 854 + VMBUS_RQST_INIT, 868 855 VM_PKT_DATA_INBAND, 869 856 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 870 857 if (ret != 0) ··· 1266 1253 const struct vmpacket_descriptor *desc; 1267 1254 struct hv_device *device; 1268 1255 struct storvsc_device *stor_device; 1256 + struct Scsi_Host *shost; 1269 1257 1270 1258 if (channel->primary_channel != NULL) 1271 1259 device = channel->primary_channel->device_obj; ··· 1277 1263 if (!stor_device) 1278 1264 return; 1279 1265 1266 + shost = stor_device->host; 1267 + 1280 1268 foreach_vmbus_pkt(desc, channel) { 1281 - void *packet = hv_pkt_data(desc); 1282 - struct storvsc_cmd_request *request; 1283 - u64 cmd_rqst; 1284 - 1285 - cmd_rqst = vmbus_request_addr(&channel->requestor, 1286 - desc->trans_id); 1287 - if (cmd_rqst == VMBUS_RQST_ERROR) { 1288 - dev_err(&device->device, 1289 - "Incorrect transaction id\n"); 1290 - continue; 1291 - } 1292 - 1293 - request = (struct storvsc_cmd_request *)(unsigned long)cmd_rqst; 1269 + struct vstor_packet *packet = hv_pkt_data(desc); 1270 + struct storvsc_cmd_request *request = NULL; 1271 + u64 rqst_id = desc->trans_id; 1294 1272 1295 1273 if (hv_pkt_datalen(desc) < sizeof(struct vstor_packet) - 1296 1274 stor_device->vmscsi_size_delta) { ··· 1290 1284 continue; 1291 1285 } 1292 1286 1293 - if (request == &stor_device->init_request || 1294 - request == &stor_device->reset_request) { 1295 - memcpy(&request->vstor_packet, packet, 1296 - (sizeof(struct vstor_packet) - stor_device->vmscsi_size_delta)); 1297 - complete(&request->wait_event); 1287 + if (rqst_id == VMBUS_RQST_INIT) { 1288 + request = &stor_device->init_request; 1289 + } else if (rqst_id == VMBUS_RQST_RESET) { 1290 + request = &stor_device->reset_request; 1298 1291 } else { 1292 + /* Hyper-V can send an unsolicited message with ID of 0 */ 1293 + if (rqst_id == 0) { 1294 + /* 1295 + * storvsc_on_receive() looks at the vstor_packet in the message 1296 + * from the ring buffer. If the operation in the vstor_packet is 1297 + * COMPLETE_IO, then we call storvsc_on_io_completion(), and 1298 + * dereference the guest memory address. Make sure we don't call 1299 + * storvsc_on_io_completion() with a guest memory address that is 1300 + * zero if Hyper-V were to construct and send such a bogus packet. 1301 + */ 1302 + if (packet->operation == VSTOR_OPERATION_COMPLETE_IO) { 1303 + dev_err(&device->device, "Invalid packet with ID of 0\n"); 1304 + continue; 1305 + } 1306 + } else { 1307 + struct scsi_cmnd *scmnd; 1308 + 1309 + /* Transaction 'rqst_id' corresponds to tag 'rqst_id - 1' */ 1310 + scmnd = scsi_host_find_tag(shost, rqst_id - 1); 1311 + if (scmnd == NULL) { 1312 + dev_err(&device->device, "Incorrect transaction ID\n"); 1313 + continue; 1314 + } 1315 + request = (struct storvsc_cmd_request *)scsi_cmd_priv(scmnd); 1316 + } 1317 + 1299 1318 storvsc_on_receive(stor_device, packet, request); 1319 + continue; 1300 1320 } 1321 + 1322 + memcpy(&request->vstor_packet, packet, 1323 + (sizeof(struct vstor_packet) - stor_device->vmscsi_size_delta)); 1324 + complete(&request->wait_event); 1301 1325 } 1302 1326 } 1303 1327 ··· 1340 1304 memset(&props, 0, sizeof(struct vmstorage_channel_properties)); 1341 1305 1342 1306 device->channel->max_pkt_size = STORVSC_MAX_PKT_SIZE; 1343 - /* 1344 - * The size of vmbus_requestor is an upper bound on the number of requests 1345 - * that can be in-progress at any one time across all channels. 1346 - */ 1347 - device->channel->rqstor_size = scsi_driver.can_queue; 1307 + device->channel->next_request_id_callback = storvsc_next_request_id; 1348 1308 1349 1309 ret = vmbus_open(device->channel, 1350 1310 ring_size, ··· 1666 1634 ret = vmbus_sendpacket(device->channel, vstor_packet, 1667 1635 (sizeof(struct vstor_packet) - 1668 1636 stor_device->vmscsi_size_delta), 1669 - (unsigned long)&stor_device->reset_request, 1637 + VMBUS_RQST_RESET, 1670 1638 VM_PKT_DATA_INBAND, 1671 1639 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); 1672 1640 if (ret != 0)
+11 -2
include/linux/hyperv.h
··· 794 794 795 795 #define VMBUS_NO_RQSTOR U64_MAX 796 796 #define VMBUS_RQST_ERROR (U64_MAX - 1) 797 + /* NetVSC-specific */ 797 798 #define VMBUS_RQST_ID_NO_RESPONSE (U64_MAX - 2) 799 + /* StorVSC-specific */ 800 + #define VMBUS_RQST_INIT (U64_MAX - 2) 801 + #define VMBUS_RQST_RESET (U64_MAX - 3) 798 802 799 803 struct vmbus_device { 800 804 u16 dev_type; ··· 1028 1024 u32 fuzz_testing_interrupt_delay; 1029 1025 u32 fuzz_testing_message_delay; 1030 1026 1027 + /* callback to generate a request ID from a request address */ 1028 + u64 (*next_request_id_callback)(struct vmbus_channel *channel, u64 rqst_addr); 1029 + /* callback to retrieve a request address from a request ID */ 1030 + u64 (*request_addr_callback)(struct vmbus_channel *channel, u64 rqst_id); 1031 + 1031 1032 /* request/transaction ids for VMBus */ 1032 1033 struct vmbus_requestor requestor; 1033 1034 u32 rqstor_size; ··· 1041 1032 u32 max_pkt_size; 1042 1033 }; 1043 1034 1044 - u64 vmbus_next_request_id(struct vmbus_requestor *rqstor, u64 rqst_addr); 1045 - u64 vmbus_request_addr(struct vmbus_requestor *rqstor, u64 trans_id); 1035 + u64 vmbus_next_request_id(struct vmbus_channel *channel, u64 rqst_addr); 1036 + u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id); 1046 1037 1047 1038 static inline bool is_hvsock_channel(const struct vmbus_channel *c) 1048 1039 {