]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/commitdiff
scsi: cxlflash: Support WS16 unmap
authorMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Fri, 7 Jul 2017 16:05:53 +0000 (13:05 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Fri, 14 Jul 2017 14:33:28 +0000 (11:33 -0300)
BugLink: http://bugs.launchpad.net/bugs/1702521
The cxlflash driver supports performing a write-same16 to scrub virtual
luns when they are released by a user. To date, AFUs for adapters that
are supported by cxlflash do not have the capability to unmap as part of
the WS operation. This can lead to fragmented flash devices which results
in performance degradation.

Future AFUs can optionally support unmap write-same commands and reflects
this support via the context control register. This provides userspace
applications with direct visibility such that they need not depend on a
host API.

Detect unmap support during cxlflash initialization by reading the context
control register associated with the primary hardware queue. Update the
existing write_same16() routine to set the unmap bit in the CDB when unmap
is supported by the host.

Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: Uma Krishnan <ukrishn@linux.vnet.ibm.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit 3223c01aa1cec60d59bd218aca5e202b558d225a)
Signed-off-by: Victor Aoqui <victora@linux.vnet.ibm.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
drivers/scsi/cxlflash/common.h
drivers/scsi/cxlflash/main.c
drivers/scsi/cxlflash/sislite.h
drivers/scsi/cxlflash/vlun.c

index a91151c4a4fc1d36e279ac1e2d49ccedc83b5bfd..e95e5a516b5eb3d92a504c88f02ea0d907b0968c 100644 (file)
@@ -147,6 +147,7 @@ struct cxlflash_cfg {
        wait_queue_head_t tmf_waitq;
        spinlock_t tmf_slock;
        bool tmf_active;
+       bool ws_unmap;          /* Write-same unmap supported */
        wait_queue_head_t reset_waitq;
        enum cxlflash_state state;
        async_cookie_t async_reset_cookie;
index d3ad52ec531487ab92bd7c4c385be3b5cf55bbed..0cce442c260adc7690217f95f33b3dbf42d816d0 100644 (file)
@@ -1812,6 +1812,18 @@ static int init_global(struct cxlflash_cfg *cfg)
                        SISL_CTX_CAP_AFU_CMD | SISL_CTX_CAP_GSCSI_CMD),
                        &hwq->ctrl_map->ctx_cap);
        }
+
+       /*
+        * Determine write-same unmap support for host by evaluating the unmap
+        * sector support bit of the context control register associated with
+        * the primary hardware queue. Note that while this status is reflected
+        * in a context register, the outcome can be assumed to be host-wide.
+        */
+       hwq = get_hwq(afu, PRIMARY_HWQ);
+       reg = readq_be(&hwq->host_map->ctx_ctrl);
+       if (reg & SISL_CTX_CTRL_UNMAP_SECTOR)
+               cfg->ws_unmap = true;
+
        /* Initialize heartbeat */
        afu->hb = readq_be(&afu->afu_map->global.regs.afu_hb);
 out:
index d671fae1969708d41c0c69aadc3adee47cb0f92b..09daa86670fcbb412ddb8f4ea01aefd707798c9e 100644 (file)
@@ -283,6 +283,7 @@ struct sisl_host_map {
        __be64 rrq_end;         /* write sequence: start followed by end */
        __be64 cmd_room;
        __be64 ctx_ctrl;        /* least significant byte or b56:63 is LISN# */
+#define SISL_CTX_CTRL_UNMAP_SECTOR     0x8000000000000000ULL /* b0 */
        __be64 mbox_w;          /* restricted use */
        __be64 sq_start;        /* Submission Queue (R/W): write sequence and */
        __be64 sq_end;          /* inclusion semantics are the same as RRQ    */
index 885b7bbc14e2f76953169942ad904ebd474330a1..6c4cd3fa816699e58a85695dfe0443a9c663eb8b 100644 (file)
@@ -446,6 +446,7 @@ static int write_same16(struct scsi_device *sdev,
        while (left > 0) {
 
                scsi_cmd[0] = WRITE_SAME_16;
+               scsi_cmd[1] = cfg->ws_unmap ? 0x8 : 0;
                put_unaligned_be64(offset, &scsi_cmd[2]);
                put_unaligned_be32(ws_limit < left ? ws_limit : left,
                                   &scsi_cmd[10]);