Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp1547349pxu; Thu, 17 Dec 2020 12:35:49 -0800 (PST) X-Google-Smtp-Source: ABdhPJxEvTqP0gDm6gv33LPRa2AXig+mbNa4OzfKdI0ZpuSC2QV2qGBRm/1NO9B+XhJL7berluK+ X-Received: by 2002:a17:906:c1c6:: with SMTP id bw6mr794082ejb.199.1608237349410; Thu, 17 Dec 2020 12:35:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608237349; cv=none; d=google.com; s=arc-20160816; b=PavNKzle65BBgNSyzRH59q18q/hoav4W4fRdqOLFKSkuLIuk5tvvq7xO0ZD5GcfSBp 6SnUOVrqDpxeoPdFNZeKctiUzR76ZFBWMfWXnkhip9dtWj3F/oMwXCegxTQicuEb9mGe +LsGCctGx+nJizZJvfv2sHPyIAT32g9tNLv4tL9GysdmgLN9QK3FBIAKQBxUOcdbqbWz OTXTVmJTRfzdE41FqNrXRGL30gjP1Z3kl8fo2R/UnbqmV3kd3JnjD7vW+2txHpF9oTa9 Rb9gU01jyw/vubAF2dJJMdm3/nvFKJsCZuCUOIOn5GWfCVv2tJwagt5n4JmuorML4NKD yYtg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=JLhYv2plnIrynx5NUImRq2YwHRg3JhpcreVENKeT2U4=; b=tyXyrM0tdi1owr2OvPflPn+mzOquQhivuEbdSUdgqSftHRa1VmkbJh//G7U0DvaTOk HmjjKeA3PC05Zizuw8rPlFUkbXKWdCvG4dcVTpBwuf8tVhiFS5l3xpDfrjME9f3DWDIq aLq+lDReD6E6Hv8K0l4C1DoB/N90KYInRQiB27knEoV4QshWVG6ZIlQScMf/Qm6YSpVq sKcTpzXYS4cPhIKoG6nKnKhx/TEV3hNvJCt5tyEkDq2zeiIK3QlLRP6Ey3ay9JQPaOWJ yuG3njHjPu0K4UvUgVYEpGRrAyxAv2RJeRwiYSZdFlJfz8Xy0gi5kpDUQ4crIhw3RGhM QzXQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=jg92lS2P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 97si5015782edr.112.2020.12.17.12.35.26; Thu, 17 Dec 2020 12:35:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=jg92lS2P; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731560AbgLQUee (ORCPT + 99 others); Thu, 17 Dec 2020 15:34:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36282 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731551AbgLQUed (ORCPT ); Thu, 17 Dec 2020 15:34:33 -0500 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53AF2C0617B0; Thu, 17 Dec 2020 12:33:53 -0800 (PST) Received: by mail-wr1-x436.google.com with SMTP id m5so27885382wrx.9; Thu, 17 Dec 2020 12:33:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JLhYv2plnIrynx5NUImRq2YwHRg3JhpcreVENKeT2U4=; b=jg92lS2PeB9kHQTADGed6FWU0rgQn4s0I7NcmsvHN6kzD8p/BCJW46DWUKr/zTOfwX xytDGg+5trVGzrmCwx1d8itL0lT6hLbAlJyS/krxW0Ed4IZCwbflVMnaAUOMa1jW9aI5 IWz66EQgfxIOnd+YmhZa/nLqoGA9k3qIe67hT8PmS6hO3EuFRehl59wE44PEvt1yWQo2 tvV8+yN/tv8c4zHyk6g9bhzS5R9T2bpFpIa0OzQBdCI6laWeXWwXN0pLQoHeuMoJwmQl C6JYG+03XqItTdLlLKXdoFpL4kPu7NvbOCL4hMxWLCZ9MsFy5eEOrbkMc+kSqblTBPWw Pk3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JLhYv2plnIrynx5NUImRq2YwHRg3JhpcreVENKeT2U4=; b=amSgmya//sOXMp+Rtxnnz0Qo3oFblQC8mWmWptLeb+RT742l7lTX2dWuDQK4GPUyQG JQ5CiiKBgrR6QW0Of7iIH9+41lm5hY+4TH1ccA8QVivP6+6dLnlA8HyIOIBhlTKMu+w9 FDhFUF4RQ2eHWNP0sbvYFEpXP7ZPHE1xMx6yoc4sG7Umzb/ABtD805oJG8sgPr2fF3uK 7gNYwomv6OkoEle6bXmlAqbo6F/o0xfcu/sO0EGSOIiu7i+dLRFptAte6yNoa/XIDia4 sY0ntDBn+BLol7p3cfiIom3WOIxb5B5C37vzfmv7tgVp9DAjgVK8BonTQBXohSlWKaDQ 1Xig== X-Gm-Message-State: AOAM532XJkhqcyzXKQeO0Kv8tuKJxjuJypsMHi3Lf8FgV2c8IUWLWnX5 BFXQ0qTdDQJX2FufeqgoKEw+T0N4siSygXLI X-Received: by 2002:a5d:6888:: with SMTP id h8mr638542wru.268.1608237231730; Thu, 17 Dec 2020 12:33:51 -0800 (PST) Received: from localhost.localdomain (host-95-239-64-30.retail.telecomitalia.it. [95.239.64.30]) by smtp.gmail.com with ESMTPSA id a62sm11729128wmh.40.2020.12.17.12.33.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Dec 2020 12:33:51 -0800 (PST) From: "Andrea Parri (Microsoft)" To: linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org Cc: "K . Y . Srinivasan" , Haiyang Zhang , Stephen Hemminger , Wei Liu , Dexuan Cui , Michael Kelley , Saruhan Karademir , Juan Vazquez , "Andrea Parri (Microsoft)" , "James E.J. Bottomley" , "Martin K. Petersen" , linux-scsi@vger.kernel.org Subject: [PATCH 2/3] scsi: storvsc: Resolve data race in storvsc_probe() Date: Thu, 17 Dec 2020 21:33:20 +0100 Message-Id: <20201217203321.4539-3-parri.andrea@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201217203321.4539-1-parri.andrea@gmail.com> References: <20201217203321.4539-1-parri.andrea@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org vmscsi_size_delta can be written concurrently by multiple instances of storvsc_probe(), corresponding to multiple synthetic IDE/SCSI devices; cf. storvsc_drv's probe_type == PROBE_PREFER_ASYNCHRONOUS. Change the global variable vmscsi_size_delta to per-synthetic-IDE/SCSI-device. Suggested-by: Dexuan Cui Signed-off-by: Andrea Parri (Microsoft) Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org --- drivers/scsi/storvsc_drv.c | 45 +++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 64298aa2f151e..8714355cb63e7 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -216,18 +216,6 @@ struct vmscsi_request { } __attribute((packed)); - -/* - * The size of the vmscsi_request has changed in win8. The - * additional size is because of new elements added to the - * structure. These elements are valid only when we are talking - * to a win8 host. - * Track the correction to size we need to apply. This value - * will likely change during protocol negotiation but it is - * valid to start by assuming pre-Win8. - */ -static int vmscsi_size_delta = sizeof(struct vmscsi_win8_extension); - /* * The list of storage protocols in order of preference. */ @@ -449,6 +437,17 @@ struct storvsc_device { unsigned char path_id; unsigned char target_id; + /* + * The size of the vmscsi_request has changed in win8. The + * additional size is because of new elements added to the + * structure. These elements are valid only when we are talking + * to a win8 host. + * Track the correction to size we need to apply. This value + * will likely change during protocol negotiation but it is + * valid to start by assuming pre-Win8. + */ + int vmscsi_size_delta; + /* * Max I/O, the device can support. */ @@ -762,7 +761,7 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns) ret = vmbus_sendpacket(device->channel, vstor_packet, (sizeof(struct vstor_packet) - - vmscsi_size_delta), + stor_device->vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -816,9 +815,14 @@ static int storvsc_execute_vstor_op(struct hv_device *device, struct storvsc_cmd_request *request, bool status_check) { + struct storvsc_device *stor_device; struct vstor_packet *vstor_packet; int ret, t; + stor_device = get_out_stor_device(device); + if (!stor_device) + return -ENODEV; + vstor_packet = &request->vstor_packet; init_completion(&request->wait_event); @@ -826,7 +830,7 @@ static int storvsc_execute_vstor_op(struct hv_device *device, ret = vmbus_sendpacket(device->channel, vstor_packet, (sizeof(struct vstor_packet) - - vmscsi_size_delta), + stor_device->vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -903,7 +907,7 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) sense_buffer_size = vmstor_protocols[i].sense_buffer_size; - vmscsi_size_delta = + stor_device->vmscsi_size_delta = vmstor_protocols[i].vmscsi_size_delta; break; @@ -1249,7 +1253,7 @@ static void storvsc_on_channel_callback(void *context) if (request == &stor_device->init_request || request == &stor_device->reset_request) { memcpy(&request->vstor_packet, packet, - (sizeof(struct vstor_packet) - vmscsi_size_delta)); + (sizeof(struct vstor_packet) - stor_device->vmscsi_size_delta)); complete(&request->wait_event); } else { storvsc_on_receive(stor_device, packet, request); @@ -1461,7 +1465,7 @@ static int storvsc_do_io(struct hv_device *device, vstor_packet->flags |= REQUEST_COMPLETION_FLAG; vstor_packet->vm_srb.length = (sizeof(struct vmscsi_request) - - vmscsi_size_delta); + stor_device->vmscsi_size_delta); vstor_packet->vm_srb.sense_info_length = sense_buffer_size; @@ -1478,12 +1482,12 @@ static int storvsc_do_io(struct hv_device *device, request->payload, request->payload_sz, vstor_packet, (sizeof(struct vstor_packet) - - vmscsi_size_delta), + stor_device->vmscsi_size_delta), (unsigned long)request); } else { ret = vmbus_sendpacket(outgoing_channel, vstor_packet, (sizeof(struct vstor_packet) - - vmscsi_size_delta), + stor_device->vmscsi_size_delta), (unsigned long)request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -1589,7 +1593,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) ret = vmbus_sendpacket(device->channel, vstor_packet, (sizeof(struct vstor_packet) - - vmscsi_size_delta), + stor_device->vmscsi_size_delta), (unsigned long)&stor_device->reset_request, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -1939,6 +1943,7 @@ static int storvsc_probe(struct hv_device *device, init_waitqueue_head(&stor_device->waiting_to_drain); stor_device->device = device; stor_device->host = host; + stor_device->vmscsi_size_delta = sizeof(struct vmscsi_win8_extension); spin_lock_init(&stor_device->lock); hv_set_drvdata(device, stor_device); -- 2.25.1