Commit 5fbb96c8 authored by Matthew R. Ochs's avatar Matthew R. Ochs Committed by Martin K. Petersen

scsi: cxlflash: Use cmd_size for private commands

Instead of using a private pool of AFU commands, use cmd_size to prime
the private pool of SCSI commands such that they are allocated with a
size large enough to contain an aligned AFU command. Use scsi_cmd_priv()
to derive the aligned/zeroed private command on queuecommand and TMF
paths. Remove cmd_checkout() as it is no longer required. The remaining
AFU private command infrastructure will be removed in a cleanup commit.
Signed-off-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Acked-by: default avatarUma Krishnan <ukrishn@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 350bb478
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/types.h> #include <linux/types.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h> #include <scsi/scsi_device.h>
extern const struct file_operations cxlflash_cxl_fops; extern const struct file_operations cxlflash_cxl_fops;
...@@ -146,6 +147,19 @@ struct afu_cmd { ...@@ -146,6 +147,19 @@ struct afu_cmd {
*/ */
} __aligned(cache_line_size()); } __aligned(cache_line_size());
static inline struct afu_cmd *sc_to_afuc(struct scsi_cmnd *sc)
{
return PTR_ALIGN(scsi_cmd_priv(sc), __alignof__(struct afu_cmd));
}
static inline struct afu_cmd *sc_to_afucz(struct scsi_cmnd *sc)
{
struct afu_cmd *afuc = sc_to_afuc(sc);
memset(afuc, 0, sizeof(*afuc));
return afuc;
}
struct afu { struct afu {
/* Stuff requiring alignment go first. */ /* Stuff requiring alignment go first. */
......
...@@ -34,38 +34,6 @@ MODULE_AUTHOR("Manoj N. Kumar <manoj@linux.vnet.ibm.com>"); ...@@ -34,38 +34,6 @@ MODULE_AUTHOR("Manoj N. Kumar <manoj@linux.vnet.ibm.com>");
MODULE_AUTHOR("Matthew R. Ochs <mrochs@linux.vnet.ibm.com>"); MODULE_AUTHOR("Matthew R. Ochs <mrochs@linux.vnet.ibm.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/**
* cmd_checkout() - checks out an AFU command
* @afu: AFU to checkout from.
*
* Commands are checked out in a round-robin fashion. Note that since
* the command pool is larger than the hardware queue, the majority of
* times we will only loop once or twice before getting a command. The
* CDB within the command is initialized (zeroed) prior to returning.
*
* Return: The checked out command or NULL when command pool is empty.
*/
static struct afu_cmd *cmd_checkout(struct afu *afu)
{
int k, dec = CXLFLASH_NUM_CMDS;
struct afu_cmd *cmd;
while (dec--) {
k = (afu->cmd_couts++ & (CXLFLASH_NUM_CMDS - 1));
cmd = &afu->cmd[k];
if (!atomic_dec_if_positive(&cmd->free)) {
pr_devel("%s: returning found index=%d cmd=%p\n",
__func__, cmd->slot, cmd);
memset(cmd->rcb.cdb, 0, sizeof(cmd->rcb.cdb));
return cmd;
}
}
return NULL;
}
/** /**
* cmd_checkin() - checks in an AFU command * cmd_checkin() - checks in an AFU command
* @cmd: AFU command to checkin. * @cmd: AFU command to checkin.
...@@ -232,7 +200,6 @@ static void cmd_complete(struct afu_cmd *cmd) ...@@ -232,7 +200,6 @@ static void cmd_complete(struct afu_cmd *cmd)
scp->result = (DID_OK << 16); scp->result = (DID_OK << 16);
cmd_is_tmf = cmd->cmd_tmf; cmd_is_tmf = cmd->cmd_tmf;
cmd_checkin(cmd); /* Don't use cmd after here */
pr_debug_ratelimited("%s: calling scsi_done scp=%p result=%X " pr_debug_ratelimited("%s: calling scsi_done scp=%p result=%X "
"ioasc=%d\n", __func__, scp, scp->result, "ioasc=%d\n", __func__, scp, scp->result,
...@@ -365,7 +332,7 @@ static void wait_resp(struct afu *afu, struct afu_cmd *cmd) ...@@ -365,7 +332,7 @@ static void wait_resp(struct afu *afu, struct afu_cmd *cmd)
*/ */
static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
{ {
struct afu_cmd *cmd; struct afu_cmd *cmd = sc_to_afucz(scp);
u32 port_sel = scp->device->channel + 1; u32 port_sel = scp->device->channel + 1;
short lflag = 0; short lflag = 0;
...@@ -376,13 +343,6 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) ...@@ -376,13 +343,6 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
int rc = 0; int rc = 0;
ulong to; ulong to;
cmd = cmd_checkout(afu);
if (unlikely(!cmd)) {
dev_err(dev, "%s: could not get a free command\n", __func__);
rc = SCSI_MLQUEUE_HOST_BUSY;
goto out;
}
/* When Task Management Function is active do not send another */ /* When Task Management Function is active do not send another */
spin_lock_irqsave(&cfg->tmf_slock, lock_flags); spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
if (cfg->tmf_active) if (cfg->tmf_active)
...@@ -394,6 +354,7 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) ...@@ -394,6 +354,7 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags); spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
cmd->rcb.ctx_id = afu->ctx_hndl; cmd->rcb.ctx_id = afu->ctx_hndl;
cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
cmd->rcb.port_sel = port_sel; cmd->rcb.port_sel = port_sel;
cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);
...@@ -402,8 +363,10 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) ...@@ -402,8 +363,10 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
cmd->rcb.req_flags = (SISL_REQ_FLAGS_PORT_LUN_ID | cmd->rcb.req_flags = (SISL_REQ_FLAGS_PORT_LUN_ID |
SISL_REQ_FLAGS_SUP_UNDERRUN | lflag); SISL_REQ_FLAGS_SUP_UNDERRUN | lflag);
/* Stash the scp in the reserved field, for reuse during interrupt */ /* Stash the scp in the command, for reuse during interrupt */
cmd->rcb.scp = scp; cmd->rcb.scp = scp;
cmd->parent = afu;
spin_lock_init(&cmd->slock);
/* Copy the CDB from the cmd passed in */ /* Copy the CDB from the cmd passed in */
memcpy(cmd->rcb.cdb, &tmfcmd, sizeof(tmfcmd)); memcpy(cmd->rcb.cdb, &tmfcmd, sizeof(tmfcmd));
...@@ -411,7 +374,6 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd) ...@@ -411,7 +374,6 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
/* Send the command */ /* Send the command */
rc = send_cmd(afu, cmd); rc = send_cmd(afu, cmd);
if (unlikely(rc)) { if (unlikely(rc)) {
cmd_checkin(cmd);
spin_lock_irqsave(&cfg->tmf_slock, lock_flags); spin_lock_irqsave(&cfg->tmf_slock, lock_flags);
cfg->tmf_active = false; cfg->tmf_active = false;
spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags); spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
...@@ -467,7 +429,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ...@@ -467,7 +429,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
struct cxlflash_cfg *cfg = (struct cxlflash_cfg *)host->hostdata; struct cxlflash_cfg *cfg = (struct cxlflash_cfg *)host->hostdata;
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct device *dev = &cfg->dev->dev; struct device *dev = &cfg->dev->dev;
struct afu_cmd *cmd; struct afu_cmd *cmd = sc_to_afucz(scp);
u32 port_sel = scp->device->channel + 1; u32 port_sel = scp->device->channel + 1;
int nseg, i, ncount; int nseg, i, ncount;
struct scatterlist *sg; struct scatterlist *sg;
...@@ -512,17 +474,11 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ...@@ -512,17 +474,11 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
break; break;
} }
cmd = cmd_checkout(afu);
if (unlikely(!cmd)) {
dev_err(dev, "%s: could not get a free command\n", __func__);
rc = SCSI_MLQUEUE_HOST_BUSY;
goto out;
}
kref_get(&cfg->afu->mapcount); kref_get(&cfg->afu->mapcount);
kref_got = 1; kref_got = 1;
cmd->rcb.ctx_id = afu->ctx_hndl; cmd->rcb.ctx_id = afu->ctx_hndl;
cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
cmd->rcb.port_sel = port_sel; cmd->rcb.port_sel = port_sel;
cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);
...@@ -536,6 +492,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ...@@ -536,6 +492,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
/* Stash the scp in the reserved field, for reuse during interrupt */ /* Stash the scp in the reserved field, for reuse during interrupt */
cmd->rcb.scp = scp; cmd->rcb.scp = scp;
cmd->parent = afu;
spin_lock_init(&cmd->slock);
nseg = scsi_dma_map(scp); nseg = scsi_dma_map(scp);
if (unlikely(nseg < 0)) { if (unlikely(nseg < 0)) {
...@@ -556,10 +514,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ...@@ -556,10 +514,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp)
/* Send the command */ /* Send the command */
rc = send_cmd(afu, cmd); rc = send_cmd(afu, cmd);
if (unlikely(rc)) { if (unlikely(rc))
cmd_checkin(cmd);
scsi_dma_unmap(scp); scsi_dma_unmap(scp);
}
out: out:
if (kref_got) if (kref_got)
...@@ -2314,6 +2270,7 @@ static struct scsi_host_template driver_template = { ...@@ -2314,6 +2270,7 @@ static struct scsi_host_template driver_template = {
.change_queue_depth = cxlflash_change_queue_depth, .change_queue_depth = cxlflash_change_queue_depth,
.cmd_per_lun = CXLFLASH_MAX_CMDS_PER_LUN, .cmd_per_lun = CXLFLASH_MAX_CMDS_PER_LUN,
.can_queue = CXLFLASH_MAX_CMDS, .can_queue = CXLFLASH_MAX_CMDS,
.cmd_size = sizeof(struct afu_cmd) + __alignof__(struct afu_cmd) - 1,
.this_id = -1, .this_id = -1,
.sg_tablesize = 1, /* No scatter gather support */ .sg_tablesize = 1, /* No scatter gather support */
.max_sectors = CXLFLASH_MAX_SECTORS, .max_sectors = CXLFLASH_MAX_SECTORS,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment