Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+29 −12
Original line number Diff line number Diff line
@@ -60,6 +60,9 @@ extern const struct file_operations cxlflash_cxl_fops;
/* SQ for master issued cmds */
#define NUM_SQ_ENTRY			CXLFLASH_MAX_CMDS

#define CXLFLASH_NUM_HWQS		1
#define PRIMARY_HWQ			0


static inline void check_sizes(void)
{
@@ -98,7 +101,6 @@ enum cxlflash_state {

struct cxlflash_cfg {
	struct afu *afu;
	struct cxl_context *mcctx;

	struct pci_dev *dev;
	struct pci_device_id *dev_id;
@@ -144,6 +146,7 @@ struct afu_cmd {
	struct list_head queue;

	u8 cmd_tmf:1;
	u32 hwq_index;

	/* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
	 * 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)
	return afuc;
}

struct afu {
struct hwq {
	/* Stuff requiring alignment go first. */
	struct sisl_ioarcb sq[NUM_SQ_ENTRY];		/* 16K SQ */
	u64 rrq_entry[NUM_RRQ_ENTRY];			/* 2K RRQ */
@@ -172,17 +175,13 @@ struct afu {
	/* Beware of alignment till here. Preferably introduce new
	 * fields after this point
	 */

	int (*send_cmd)(struct afu *, struct afu_cmd *);
	void (*context_reset)(struct afu_cmd *);

	/* AFU HW */
	struct afu *afu;
	struct cxl_context *ctx;
	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_ctrl_map __iomem *ctrl_map;		/* MC control map */

	ctx_hndl_t ctx_hndl;	/* master's context handle */
	u32 index;		/* Index of this hwq */

	atomic_t hsq_credits;
	spinlock_t hsq_slock;
@@ -194,9 +193,22 @@ struct afu {
	u64 *hrrq_end;
	u64 *hrrq_curr;
	bool toggle;
	atomic_t cmds_active;	/* Number of currently active AFU commands */

	s64 room;
	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;
	u32 internal_lun;	/* User-desired LUN mode for this AFU */

@@ -204,11 +216,16 @@ struct afu {
	u64 interface_version;

	u32 irqpoll_weight;
	struct irq_poll irqpoll;
	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)
{
	return !!afu->irqpoll_weight;
+276 −150

File changed.

Preview size limit exceeded, changes collapsed.

+4 −2
Original line number Diff line number Diff line
@@ -254,6 +254,7 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
	struct afu *afu = cfg->afu;
	struct sisl_ctrl_map __iomem *ctrl_map = ctxi->ctrl_map;
	int rc = 0;
	struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
	u64 val;

	/* 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)

	/* Set up MMIO registers pointing to the RHT */
	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);
out:
	dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
@@ -1626,6 +1627,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
	struct afu *afu = cfg->afu;
	struct ctx_info *ctxi = NULL;
	struct mutex *mutex = &cfg->ctx_recovery_mutex;
	struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
	u64 flags;
	u64 ctxid = DECODE_CTXID(recover->context_id),
	    rctxid = recover->context_id;
@@ -1696,7 +1698,7 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
	}

	/* Test if in error state */
	reg = readq_be(&afu->ctrl_map->mbox_r);
	reg = readq_be(&hwq->ctrl_map->mbox_r);
	if (reg == -1) {
		dev_dbg(dev, "%s: MMIO fail, wait for recovery.\n", __func__);