From patchwork Tue Mar 29 03:13:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 8681751 Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id C570BC0553 for ; Tue, 29 Mar 2016 03:18:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B6D6C20145 for ; Tue, 29 Mar 2016 03:18:38 +0000 (UTC) Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E5C320142 for ; Tue, 29 Mar 2016 03:18:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id u2T3FhWA032462; Mon, 28 Mar 2016 23:15:43 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id u2T3DRbn014231 for ; Mon, 28 Mar 2016 23:13:27 -0400 Received: from redhat.com (octiron.msp.redhat.com [10.15.80.209]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id u2T3DQCM019850; Mon, 28 Mar 2016 23:13:26 -0400 Received: by redhat.com (sSMTP sendmail emulation); Mon, 28 Mar 2016 22:13:26 -0500 From: "Benjamin Marzinski" To: device-mapper development Date: Mon, 28 Mar 2016 22:13:04 -0500 Message-Id: <1459221194-23222-8-git-send-email-bmarzins@redhat.com> In-Reply-To: <1459221194-23222-1-git-send-email-bmarzins@redhat.com> References: <1459221194-23222-1-git-send-email-bmarzins@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH 07/17] libmultipath: Cut down on alua prioritizer ioctls X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-7.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, running the alua prioritizer on a path causes 5 ioctls on many devices. get_target_port_group_support() returns whether alua is supported. get_target_port_group() gets the TPG id. This often takes two ioctls because 128 bytes is not a large enough buffer size on many devices. Finally, get_asymmetric_access_state() also often takes two ioctls because of the buffer size. This can get to be problematic when there are thousands of paths. The goal of this patch to to cut this down to one call in the usual case. In order to do this, get_target_port_group_support() is now only called when get_target_port_group() fails, to provide a more useful error message. Also, before doing an SGIO ioctl to get the vpd83 data, multipath first tries to read it from sysfs. Signed-off-by: Benjamin Marzinski --- libmultipath/discovery.h | 2 + libmultipath/prioritizers/alua.c | 24 ++++++------ libmultipath/prioritizers/alua_rtpg.c | 69 ++++++++++++++++++++++++----------- libmultipath/prioritizers/alua_rtpg.h | 2 +- libmultipath/propsel.c | 2 +- 5 files changed, 63 insertions(+), 36 deletions(-) diff --git a/libmultipath/discovery.h b/libmultipath/discovery.h index da7652c..5931bc6 100644 --- a/libmultipath/discovery.h +++ b/libmultipath/discovery.h @@ -45,6 +45,8 @@ int sysfs_set_scsi_tmo (struct multipath *mpp); int sysfs_get_timeout(struct path *pp, unsigned int *timeout); int sysfs_get_host_pci_name(struct path *pp, char *pci_name); int sysfs_get_iscsi_ip_address(struct path *pp, char *ip_address); +ssize_t sysfs_get_vpd (struct udev_device * udev, int pg, unsigned char * buff, + size_t len); /* * discovery bitmask diff --git a/libmultipath/prioritizers/alua.c b/libmultipath/prioritizers/alua.c index 39ed1c8..0bd374f 100644 --- a/libmultipath/prioritizers/alua.c +++ b/libmultipath/prioritizers/alua.c @@ -51,24 +51,22 @@ static const char *aas_print_string(int rc) } int -get_alua_info(int fd) +get_alua_info(struct path * pp) { int rc; int tpg; - rc = get_target_port_group_support(fd); - if (rc < 0) - return -ALUA_PRIO_TPGS_FAILED; - - if (rc == TPGS_NONE) - return -ALUA_PRIO_NOT_SUPPORTED; - - tpg = get_target_port_group(fd); - if (tpg < 0) + tpg = get_target_port_group(pp); + if (tpg < 0) { + rc = get_target_port_group_support(pp->fd); + if (rc < 0) + return -ALUA_PRIO_TPGS_FAILED; + if (rc == TPGS_NONE) + return -ALUA_PRIO_NOT_SUPPORTED; return -ALUA_PRIO_RTPG_FAILED; - + } condlog(3, "reported target port group is %i", tpg); - rc = get_asymmetric_access_state(fd, tpg); + rc = get_asymmetric_access_state(pp->fd, tpg); if (rc < 0) return -ALUA_PRIO_GETAAS_FAILED; @@ -86,7 +84,7 @@ int getprio (struct path * pp, char * args) if (pp->fd < 0) return -ALUA_PRIO_NO_INFORMATION; - rc = get_alua_info(pp->fd); + rc = get_alua_info(pp); if (rc >= 0) { aas = (rc & 0x0f); priopath = (rc & 0x80); diff --git a/libmultipath/prioritizers/alua_rtpg.c b/libmultipath/prioritizers/alua_rtpg.c index 6d04fc1..636aae5 100644 --- a/libmultipath/prioritizers/alua_rtpg.c +++ b/libmultipath/prioritizers/alua_rtpg.c @@ -17,15 +17,18 @@ #include #include #include +#include #define __user #include +#include "../structs.h" #include "../prio.h" +#include "../discovery.h" #include "alua_rtpg.h" #define SENSE_BUFF_LEN 32 -#define DEF_TIMEOUT 60000 +#define SGIO_TIMEOUT 60000 /* * Macro used to print debug messaged. @@ -135,7 +138,7 @@ do_inquiry(int fd, int evpd, unsigned int codepage, void *resp, int resplen) hdr.dxfer_len = resplen; hdr.sbp = sense; hdr.mx_sb_len = sizeof(sense); - hdr.timeout = get_prio_timeout(DEF_TIMEOUT); + hdr.timeout = get_prio_timeout(SGIO_TIMEOUT); if (ioctl(fd, SG_IO, &hdr) < 0) { PRINT_DEBUG("do_inquiry: IOCTL failed!\n"); @@ -170,8 +173,27 @@ get_target_port_group_support(int fd) return rc; } +static int +get_sysfs_pg83(struct path *pp, unsigned char *buff, int buflen) +{ + struct udev_device *parent = pp->udev; + + while (parent) { + const char *subsys = udev_device_get_subsystem(parent); + if (subsys && !strncmp(subsys, "scsi", 4)) + break; + parent = udev_device_get_parent(parent); + } + + if (!parent || sysfs_get_vpd(parent, 0x83, buff, buflen) <= 0) { + PRINT_DEBUG("failed to read sysfs vpd pg83\n"); + return -1; + } + return 0; +} + int -get_target_port_group(int fd) +get_target_port_group(struct path * pp) { unsigned char *buf; struct vpd83_data * vpd83; @@ -179,7 +201,7 @@ get_target_port_group(int fd) int rc; int buflen, scsi_buflen; - buflen = 128; /* Lets start from 128 */ + buflen = 4096; buf = (unsigned char *)malloc(buflen); if (!buf) { PRINT_DEBUG("malloc failed: could not allocate" @@ -188,24 +210,29 @@ get_target_port_group(int fd) } memset(buf, 0, buflen); - rc = do_inquiry(fd, 1, 0x83, buf, buflen); - if (rc < 0) - goto out; - scsi_buflen = (buf[2] << 8 | buf[3]) + 4; - if (buflen < scsi_buflen) { - free(buf); - buf = (unsigned char *)malloc(scsi_buflen); - if (!buf) { - PRINT_DEBUG("malloc failed: could not allocate" - "%u bytes\n", scsi_buflen); - return -RTPG_RTPG_FAILED; - } - buflen = scsi_buflen; - memset(buf, 0, buflen); - rc = do_inquiry(fd, 1, 0x83, buf, buflen); + rc = get_sysfs_pg83(pp, buf, buflen); + + if (rc < 0) { + rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen); if (rc < 0) goto out; + + scsi_buflen = (buf[2] << 8 | buf[3]) + 4; + if (buflen < scsi_buflen) { + free(buf); + buf = (unsigned char *)malloc(scsi_buflen); + if (!buf) { + PRINT_DEBUG("malloc failed: could not allocate" + "%u bytes\n", scsi_buflen); + return -RTPG_RTPG_FAILED; + } + buflen = scsi_buflen; + memset(buf, 0, buflen); + rc = do_inquiry(pp->fd, 1, 0x83, buf, buflen); + if (rc < 0) + goto out; + } } vpd83 = (struct vpd83_data *) buf; @@ -254,7 +281,7 @@ do_rtpg(int fd, void* resp, long resplen) hdr.dxfer_len = resplen; hdr.mx_sb_len = sizeof(sense); hdr.sbp = sense; - hdr.timeout = get_prio_timeout(DEF_TIMEOUT); + hdr.timeout = get_prio_timeout(SGIO_TIMEOUT); if (ioctl(fd, SG_IO, &hdr) < 0) return -RTPG_RTPG_FAILED; @@ -278,7 +305,7 @@ get_asymmetric_access_state(int fd, unsigned int tpg) int buflen; uint32_t scsi_buflen; - buflen = 128; /* Initial value from old code */ + buflen = 4096; buf = (unsigned char *)malloc(buflen); if (!buf) { PRINT_DEBUG ("malloc failed: could not allocate" diff --git a/libmultipath/prioritizers/alua_rtpg.h b/libmultipath/prioritizers/alua_rtpg.h index c43e0a9..91a15a4 100644 --- a/libmultipath/prioritizers/alua_rtpg.h +++ b/libmultipath/prioritizers/alua_rtpg.h @@ -23,7 +23,7 @@ #define RTPG_TPG_NOT_FOUND 4 int get_target_port_group_support(int fd); -int get_target_port_group(int fd); +int get_target_port_group(struct path * pp); int get_asymmetric_access_state(int fd, unsigned int tpg); #endif /* __RTPG_H__ */ diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c index 890d4b1..8abe360 100644 --- a/libmultipath/propsel.c +++ b/libmultipath/propsel.c @@ -378,7 +378,7 @@ detect_prio(struct path * pp) if ((tpgs = get_target_port_group_support(pp->fd)) <= 0) return; pp->tpgs = tpgs; - ret = get_target_port_group(pp->fd); + ret = get_target_port_group(pp); if (ret < 0) return; if (get_asymmetric_access_state(pp->fd, ret) < 0)