From nobody Tue Apr 30 18:18:40 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org; Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 1497889316276378.97341056184314; Mon, 19 Jun 2017 09:21:56 -0700 (PDT) Received: from [127.0.0.1] (helo=ra.coresystems.de) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1dMzPY-0003be-9n; Mon, 19 Jun 2017 18:20:20 +0200 Received: from mx1.redhat.com ([209.132.183.28]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1dMzPO-0003ac-Jw for seabios@seabios.org; Mon, 19 Jun 2017 18:20:18 +0200 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B140D40F0D; Mon, 19 Jun 2017 16:21:13 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-117-163.ams2.redhat.com [10.36.117.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id BC14217C36; Mon, 19 Jun 2017 16:21:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B140D40F0D Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=pbonzini@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com B140D40F0D From: Paolo Bonzini To: seabios@seabios.org Date: Mon, 19 Jun 2017 18:21:09 +0200 Message-Id: <20170619162110.28156-2-pbonzini@redhat.com> In-Reply-To: <20170619162110.28156-1-pbonzini@redhat.com> References: <20170619162110.28156-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 19 Jun 2017 16:21:13 +0000 (UTC) X-Spam-Score: -6.5 (------) Subject: [SeaBIOS] [PATCH 1/2] scsi: ensure LUN0 is added first X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The introduction of REPORT LUNS caused a potential regression when many disks are present on the same SCSI target. If LUN0 is processed too late, SeaBIOS might run out of memory and fail to register it. There are two kinds of problems: - QEMU presents the results of REPORT LUNS in the opposite order to the "-device" command-line options. It's likely that LUN 0 will be first in the command-line, and thus will be processed last by SeaBIOS. - QEMU registers all LUNs in each target first. It's thus possible that LUN 0 of target 1 is processed after many LUNs of target 0 and not be able to allocate memory. To fix both, the SCSI scans are modified to operate in two phases; LUN 0 is scanned before the REPORT LUNS command is sent. A possible future enhancement is to remember the results of the scan in a 32-byte bitmap, and skip the REPORT LUNS command during the second phase. When multiple SCSI controllers are found, it's still possible to have a regression because they are scanned in parallel. Signed-off-by: Paolo Bonzini --- src/hw/blockcmd.c | 4 ++-- src/hw/esp-scsi.c | 10 ++++++++-- src/hw/lsi-scsi.c | 10 ++++++++-- src/hw/mpt-scsi.c | 10 ++++++++-- src/hw/usb-uas.c | 1 + src/hw/virtio-scsi.c | 13 +++++++++---- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/hw/blockcmd.c b/src/hw/blockcmd.c index 324188d..af9cd4d 100644 --- a/src/hw/blockcmd.c +++ b/src/hw/blockcmd.c @@ -254,7 +254,7 @@ int scsi_rep_luns_scan(struct drive_s *tmp_drive, scsi_= add_lun add_lun) =20 for (i =3D 0, ret =3D 0; i < nluns; i++) { u64 lun =3D scsilun2u64(&resp->luns[i]); - if (lun >> 32) + if (lun >> 32 || !lun) continue; ret +=3D !add_lun((u32)lun, tmp_drive); } @@ -270,7 +270,7 @@ int scsi_sequential_scan(struct drive_s *tmp_drive, u32= maxluns, int ret; u32 lun; =20 - for (lun =3D 0, ret =3D 0; lun < maxluns; lun++) + for (lun =3D 1, ret =3D 0; lun < maxluns; lun++) ret +=3D !add_lun(lun, tmp_drive); return ret; } diff --git a/src/hw/esp-scsi.c b/src/hw/esp-scsi.c index 57d3832..a2f6cbc 100644 --- a/src/hw/esp-scsi.c +++ b/src/hw/esp-scsi.c @@ -194,11 +194,15 @@ fail: } =20 static void -esp_scsi_scan_target(struct pci_device *pci, u32 iobase, u8 target) +esp_scsi_scan_target(struct pci_device *pci, u32 iobase, u8 target, u8 rep= ort_luns) { struct esp_lun_s llun0; =20 esp_scsi_init_lun(&llun0, pci, iobase, target, 0); + if (!report_luns) { + esp_scsi_add_lun(0, &llun0.drive); + return; + } =20 scsi_rep_luns_scan(&llun0.drive, esp_scsi_add_lun); } @@ -219,7 +223,9 @@ init_esp_scsi(void *data) =20 int i; for (i =3D 0; i <=3D 7; i++) - esp_scsi_scan_target(pci, iobase, i); + esp_scsi_scan_target(pci, iobase, i, 0); + for (i =3D 0; i <=3D 7; i++) + esp_scsi_scan_target(pci, iobase, i, 1); } =20 void diff --git a/src/hw/lsi-scsi.c b/src/hw/lsi-scsi.c index 846bb0b..bf2ff76 100644 --- a/src/hw/lsi-scsi.c +++ b/src/hw/lsi-scsi.c @@ -175,11 +175,15 @@ fail: } =20 static void -lsi_scsi_scan_target(struct pci_device *pci, u32 iobase, u8 target) +lsi_scsi_scan_target(struct pci_device *pci, u32 iobase, u8 target, u8 rep= ort_luns) { struct lsi_lun_s llun0; =20 lsi_scsi_init_lun(&llun0, pci, iobase, target, 0); + if (!report_luns) { + lsi_scsi_add_lun(0, &llun0.drive); + return; + } =20 if (scsi_rep_luns_scan(&llun0.drive, lsi_scsi_add_lun) < 0) scsi_sequential_scan(&llun0.drive, 8, lsi_scsi_add_lun); @@ -201,7 +205,9 @@ init_lsi_scsi(void *data) =20 int i; for (i =3D 0; i < 7; i++) - lsi_scsi_scan_target(pci, iobase, i); + lsi_scsi_scan_target(pci, iobase, i, 0); + for (i =3D 0; i < 7; i++) + lsi_scsi_scan_target(pci, iobase, i, 1); } =20 void diff --git a/src/hw/mpt-scsi.c b/src/hw/mpt-scsi.c index 80c6d6b..5a412aa 100644 --- a/src/hw/mpt-scsi.c +++ b/src/hw/mpt-scsi.c @@ -237,11 +237,15 @@ fail: } =20 static void -mpt_scsi_scan_target(struct pci_device *pci, u32 iobase, u8 target) +mpt_scsi_scan_target(struct pci_device *pci, u32 iobase, u8 target, u8 rep= ort_luns) { struct mpt_lun_s llun0; =20 mpt_scsi_init_lun(&llun0, pci, iobase, target, 0); + if (!report_luns) { + mpt_scsi_add_lun(0, &llun0.drive); + return; + } =20 if (scsi_rep_luns_scan(&llun0.drive, mpt_scsi_add_lun) < 0) scsi_sequential_scan(&llun0.drive, 8, mpt_scsi_add_lun); @@ -295,7 +299,9 @@ init_mpt_scsi(void *data) =20 int i; for (i =3D 0; i < 7; i++) - mpt_scsi_scan_target(pci, iobase, i); + mpt_scsi_scan_target(pci, iobase, i, 0); + for (i =3D 0; i < 7; i++) + mpt_scsi_scan_target(pci, iobase, i, 1); } =20 void diff --git a/src/hw/usb-uas.c b/src/hw/usb-uas.c index f00221a..f2eb049 100644 --- a/src/hw/usb-uas.c +++ b/src/hw/usb-uas.c @@ -272,6 +272,7 @@ usb_uas_setup(struct usbdevice_s *usbdev) =20 struct uasdrive_s lun0; uas_init_lun(&lun0, usbdev, command, status, data_in, data_out, 0); + uas_add_lun(0, &lun0.drive); int ret =3D scsi_rep_luns_scan(&lun0.drive, uas_add_lun); if (ret <=3D 0) { dprintf(1, "Unable to configure UAS drive.\n"); diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c index 7490ec0..3e8f13e 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -135,12 +135,14 @@ fail: =20 static int virtio_scsi_scan_target(struct pci_device *pci, struct vp_device *vp, - struct vring_virtqueue *vq, u16 target) + struct vring_virtqueue *vq, u16 target, u8 report_= luns) { =20 struct virtio_lun_s vlun0; =20 virtio_scsi_init_lun(&vlun0, pci, vp, vq, target, 0); + if (!report_luns) + return !virtio_scsi_add_lun(0, &vlun0.drive); =20 int ret =3D scsi_rep_luns_scan(&vlun0.drive, virtio_scsi_add_lun); return ret < 0 ? 0 : ret; @@ -185,9 +187,12 @@ init_virtio_scsi(void *data) status |=3D VIRTIO_CONFIG_S_DRIVER_OK; vp_set_status(vp, status); =20 - int i, tot; - for (tot =3D 0, i =3D 0; i < 256; i++) - tot +=3D virtio_scsi_scan_target(pci, vp, vq, i); + int tot =3D 0; + int i; + for (i =3D 0; i < 256; i++) + tot +=3D virtio_scsi_scan_target(pci, vp, vq, i, 0); + for (i =3D 0; i < 256; i++) + tot +=3D virtio_scsi_scan_target(pci, vp, vq, i, 1); =20 if (!tot) goto fail; --=20 2.13.0 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios From nobody Tue Apr 30 18:18:40 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zoho.com; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org; Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 14978893075597.539738773821227; Mon, 19 Jun 2017 09:21:47 -0700 (PDT) Received: from [127.0.0.1] (helo=ra.coresystems.de) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1dMzPd-0003cN-4L; Mon, 19 Jun 2017 18:20:25 +0200 Received: from mx1.redhat.com ([209.132.183.28]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1dMzPP-0003ad-K9 for seabios@seabios.org; Mon, 19 Jun 2017 18:20:23 +0200 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C0BCB80C15; Mon, 19 Jun 2017 16:21:14 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-117-163.ams2.redhat.com [10.36.117.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0AE1F17C36; Mon, 19 Jun 2017 16:21:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C0BCB80C15 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=pbonzini@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com C0BCB80C15 From: Paolo Bonzini To: seabios@seabios.org Date: Mon, 19 Jun 2017 18:21:10 +0200 Message-Id: <20170619162110.28156-3-pbonzini@redhat.com> In-Reply-To: <20170619162110.28156-1-pbonzini@redhat.com> References: <20170619162110.28156-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Mon, 19 Jun 2017 16:21:14 +0000 (UTC) X-Spam-Score: -6.5 (------) Subject: [SeaBIOS] [PATCH 2/2] virtio-scsi: speed up SCSI bus scan X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The introduction of REPORT LUNS caused virtio-scsi to send two SCSI commands (INQUIRY and REPORT LUNS) to each target rather than just one. However, INQUIRY will only fail if _no_ LUN is present on that target. If all devices have LUN>0 is present, INQUIRY will report a dummy device. Therefore, the LUN0 scan can be used to prepare a compact bitmap of targets that we have to scan, and omit sending REPORT LUNS to the others. Signed-off-by: Paolo Bonzini --- src/hw/blockcmd.c | 2 ++ src/hw/virtio-scsi.c | 45 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/hw/blockcmd.c b/src/hw/blockcmd.c index af9cd4d..32d8d68 100644 --- a/src/hw/blockcmd.c +++ b/src/hw/blockcmd.c @@ -276,6 +276,8 @@ int scsi_sequential_scan(struct drive_s *tmp_drive, u32= maxluns, } =20 // Validate drive, find block size / sector count, and register drive. +// Return positive value if disk error, 0 if success, negative if +// not a disk or the disk parameters are invalid. int scsi_drive_setup(struct drive_s *drive, const char *s, int prio) { diff --git a/src/hw/virtio-scsi.c b/src/hw/virtio-scsi.c index 3e8f13e..ad09701 100644 --- a/src/hw/virtio-scsi.c +++ b/src/hw/virtio-scsi.c @@ -130,22 +130,40 @@ virtio_scsi_add_lun(u32 lun, struct drive_s *tmpl_drv) =20 fail: free(vlun); - return -1; + return ret; } =20 static int virtio_scsi_scan_target(struct pci_device *pci, struct vp_device *vp, - struct vring_virtqueue *vq, u16 target, u8 report_= luns) + struct vring_virtqueue *vq, u16 target, u32 *targe= ts, + u8 report_luns) { =20 struct virtio_lun_s vlun0; =20 virtio_scsi_init_lun(&vlun0, pci, vp, vq, target, 0); - if (!report_luns) - return !virtio_scsi_add_lun(0, &vlun0.drive); - - int ret =3D scsi_rep_luns_scan(&vlun0.drive, virtio_scsi_add_lun); - return ret < 0 ? 0 : ret; + dprintf(3, "scanning target %d, pass %d\n", target, report_luns); + if (!report_luns) { + int ret =3D virtio_scsi_add_lun(0, &vlun0.drive); + if (ret > 0) { + /* Target error */ + return 0; + } + /* Found a SCSI device (maybe not a disk if ret < 0). Search high= er + * LUNs in the second pass. + */ + dprintf(1, "will scan target %d\n", target); + targets[target >> 5] |=3D 1 << (target & 31); + return !ret; + } else { + int ret =3D 0; + if (targets[target >> 5] & (1 << (target & 31))) { + ret =3D scsi_rep_luns_scan(&vlun0.drive, virtio_scsi_add_lun); + if (ret < 0) + ret =3D 0; + } + return ret; + } } =20 static void @@ -188,11 +206,18 @@ init_virtio_scsi(void *data) vp_set_status(vp, status); =20 int tot =3D 0; + u32 targets[256 / 32]; int i; + memset(targets, 0, sizeof(targets)); for (i =3D 0; i < 256; i++) - tot +=3D virtio_scsi_scan_target(pci, vp, vq, i, 0); - for (i =3D 0; i < 256; i++) - tot +=3D virtio_scsi_scan_target(pci, vp, vq, i, 1); + tot +=3D virtio_scsi_scan_target(pci, vp, vq, i, targets, 0); + for (i =3D 0; i < 256; i++) { + if (!targets[i >> 5]) { + i |=3D 31; + continue; + } + tot +=3D virtio_scsi_scan_target(pci, vp, vq, i, targets, 1); + } =20 if (!tot) goto fail; --=20 2.13.0 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios