Commit bfc0bab1 authored by Uma Krishnan's avatar Uma Krishnan Committed by Martin K. Petersen

scsi: cxlflash: Support multiple hardware queues

Introduce multiple hardware queues to improve legacy I/O path performance.
Each hardware queue is comprised of a master context and associated I/O
resources. The hardware queues are initially implemented as a static array
embedded in the AFU. This will be transitioned to a dynamic allocation in a
later series to improve the memory footprint of the driver.
Signed-off-by: default avatarUma Krishnan <ukrishn@linux.vnet.ibm.com>
Acked-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e2ef33fa
...@@ -60,6 +60,9 @@ extern const struct file_operations cxlflash_cxl_fops; ...@@ -60,6 +60,9 @@ extern const struct file_operations cxlflash_cxl_fops;
/* SQ for master issued cmds */ /* SQ for master issued cmds */
#define NUM_SQ_ENTRY CXLFLASH_MAX_CMDS #define NUM_SQ_ENTRY CXLFLASH_MAX_CMDS
#define CXLFLASH_NUM_HWQS 1
#define PRIMARY_HWQ 0
static inline void check_sizes(void) static inline void check_sizes(void)
{ {
...@@ -98,7 +101,6 @@ enum cxlflash_state { ...@@ -98,7 +101,6 @@ enum cxlflash_state {
struct cxlflash_cfg { struct cxlflash_cfg {
struct afu *afu; struct afu *afu;
struct cxl_context *mcctx;
struct pci_dev *dev; struct pci_dev *dev;
struct pci_device_id *dev_id; struct pci_device_id *dev_id;
...@@ -144,6 +146,7 @@ struct afu_cmd { ...@@ -144,6 +146,7 @@ struct afu_cmd {
struct list_head queue; struct list_head queue;
u8 cmd_tmf:1; u8 cmd_tmf:1;
u32 hwq_index;
/* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned. /* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
* However for performance reasons the IOARCB/IOASA should be * However for performance reasons the IOARCB/IOASA should be
...@@ -164,7 +167,7 @@ static inline struct afu_cmd *sc_to_afucz(struct scsi_cmnd *sc) ...@@ -164,7 +167,7 @@ static inline struct afu_cmd *sc_to_afucz(struct scsi_cmnd *sc)
return afuc; return afuc;
} }
struct afu { struct hwq {
/* Stuff requiring alignment go first. */ /* Stuff requiring alignment go first. */
struct sisl_ioarcb sq[NUM_SQ_ENTRY]; /* 16K SQ */ struct sisl_ioarcb sq[NUM_SQ_ENTRY]; /* 16K SQ */
u64 rrq_entry[NUM_RRQ_ENTRY]; /* 2K RRQ */ u64 rrq_entry[NUM_RRQ_ENTRY]; /* 2K RRQ */
...@@ -172,17 +175,13 @@ struct afu { ...@@ -172,17 +175,13 @@ struct afu {
/* Beware of alignment till here. Preferably introduce new /* Beware of alignment till here. Preferably introduce new
* fields after this point * fields after this point
*/ */
struct afu *afu;
int (*send_cmd)(struct afu *, struct afu_cmd *); struct cxl_context *ctx;
void (*context_reset)(struct afu_cmd *);
/* AFU HW */
struct cxl_ioctl_start_work work; struct cxl_ioctl_start_work work;
struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
struct sisl_host_map __iomem *host_map; /* MC host map */ struct sisl_host_map __iomem *host_map; /* MC host map */
struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */
ctx_hndl_t ctx_hndl; /* master's context handle */ ctx_hndl_t ctx_hndl; /* master's context handle */
u32 index; /* Index of this hwq */
atomic_t hsq_credits; atomic_t hsq_credits;
spinlock_t hsq_slock; spinlock_t hsq_slock;
...@@ -194,9 +193,22 @@ struct afu { ...@@ -194,9 +193,22 @@ struct afu {
u64 *hrrq_end; u64 *hrrq_end;
u64 *hrrq_curr; u64 *hrrq_curr;
bool toggle; bool toggle;
atomic_t cmds_active; /* Number of currently active AFU commands */
s64 room; s64 room;
spinlock_t rrin_slock; /* Lock to rrin queuing and cmd_room updates */ spinlock_t rrin_slock; /* Lock to rrin queuing and cmd_room updates */
struct irq_poll irqpoll;
} __aligned(cache_line_size());
struct afu {
struct hwq hwqs[CXLFLASH_NUM_HWQS];
int (*send_cmd)(struct afu *, struct afu_cmd *);
void (*context_reset)(struct afu_cmd *);
/* AFU HW */
struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
atomic_t cmds_active; /* Number of currently active AFU commands */
u64 hb; u64 hb;
u32 internal_lun; /* User-desired LUN mode for this AFU */ u32 internal_lun; /* User-desired LUN mode for this AFU */
...@@ -204,11 +216,16 @@ struct afu { ...@@ -204,11 +216,16 @@ struct afu {
u64 interface_version; u64 interface_version;
u32 irqpoll_weight; u32 irqpoll_weight;
struct irq_poll irqpoll;
struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */ struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
}; };
static inline struct hwq *get_hwq(struct afu *afu, u32 index)
{
WARN_ON(index >= CXLFLASH_NUM_HWQS);
return &afu->hwqs[index];
}
static inline bool afu_is_irqpoll_enabled(struct afu *afu) static inline bool afu_is_irqpoll_enabled(struct afu *afu)
{ {
return !!afu->irqpoll_weight; return !!afu->irqpoll_weight;
......
This diff is collapsed.
...@@ -254,6 +254,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) ...@@ -254,6 +254,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct sisl_ctrl_map __iomem *ctrl_map = ctxi->ctrl_map; struct sisl_ctrl_map __iomem *ctrl_map = ctxi->ctrl_map;
int rc = 0; int rc = 0;
struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
u64 val; u64 val;
/* Unlock cap and restrict user to read/write cmds in translated mode */ /* Unlock cap and restrict user to read/write cmds in translated mode */
...@@ -270,7 +271,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) ...@@ -270,7 +271,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
/* Set up MMIO registers pointing to the RHT */ /* Set up MMIO registers pointing to the RHT */
writeq_be((u64)ctxi->rht_start, &ctrl_map->rht_start); writeq_be((u64)ctxi->rht_start, &ctrl_map->rht_start);
val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(afu->ctx_hndl)); val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(hwq->ctx_hndl));
writeq_be(val, &ctrl_map->rht_cnt_id); writeq_be(val, &ctrl_map->rht_cnt_id);
out: out:
dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc); dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
...@@ -1626,6 +1627,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev, ...@@ -1626,6 +1627,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
struct afu *afu = cfg->afu; struct afu *afu = cfg->afu;
struct ctx_info *ctxi = NULL; struct ctx_info *ctxi = NULL;
struct mutex *mutex = &cfg->ctx_recovery_mutex; struct mutex *mutex = &cfg->ctx_recovery_mutex;
struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
u64 flags; u64 flags;
u64 ctxid = DECODE_CTXID(recover->context_id), u64 ctxid = DECODE_CTXID(recover->context_id),
rctxid = recover->context_id; rctxid = recover->context_id;
...@@ -1696,7 +1698,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev, ...@@ -1696,7 +1698,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
} }
/* Test if in error state */ /* Test if in error state */
reg = readq_be(&afu->ctrl_map->mbox_r); reg = readq_be(&hwq->ctrl_map->mbox_r);
if (reg == -1) { if (reg == -1) {
dev_dbg(dev, "%s: MMIO fail, wait for recovery.\n", __func__); dev_dbg(dev, "%s: MMIO fail, wait for recovery.\n", __func__);
......
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