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

Commit 48ea2ced authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI target updates from Nicholas Bellinger:
 "It's been usually busy for summer, with most of the efforts centered
  around TCMU developments and various target-core + fabric driver bug
  fixing activities. Not particularly large in terms of LoC, but lots of
  smaller patches from many different folks.

  The highlights include:

   - ibmvscsis logical partition manager support (Michael Cyr + Bryant
     Ly)

   - Convert target/iblock WRITE_SAME to blkdev_issue_zeroout (hch +
     nab)

   - Add support for TMR percpu LUN reference counting (nab)

   - Fix a potential deadlock between EXTENDED_COPY and iscsi shutdown
     (Bart)

   - Fix COMPARE_AND_WRITE caw_sem leak during se_cmd quiesce (Jiang Yi)

   - Fix TMCU module removal (Xiubo Li)

   - Fix iser-target OOPs during login failure (Andrea Righi + Sagi)

   - Breakup target-core free_device backend driver callback (mnc)

   - Perform TCMU add/delete/reconfig synchronously (mnc)

   - Fix TCMU multiple UIO open/close sequences (mnc)

   - Fix TCMU CHECK_CONDITION sense handling (mnc)

   - Fix target-core SAM_STAT_BUSY + TASK_SET_FULL handling (mnc + nab)

   - Introduce TYPE_ZBC support in PSCSI (Damien Le Moal)

   - Fix possible TCMU memory leak + OOPs when recalculating cmd base
     size (Xiubo Li + Bryant Ly + Damien Le Moal + mnc)

   - Add login_keys_workaround attribute for non RFC initiators (Robert
     LeBlanc + Arun Easi + nab)"

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (68 commits)
  iscsi-target: Add login_keys_workaround attribute for non RFC initiators
  Revert "qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT"
  tcmu: clean up the code and with one small fix
  tcmu: Fix possbile memory leak / OOPs when recalculating cmd base size
  target: export lio pgr/alua support as device attr
  target: Fix return sense reason in target_scsi3_emulate_pr_out
  target: Fix cmd size for PR-OUT in passthrough_parse_cdb
  tcmu: Fix dev_config_store
  target: pscsi: Introduce TYPE_ZBC support
  target: Use macro for WRITE_VERIFY_32 operation codes
  target: fix SAM_STAT_BUSY/TASK_SET_FULL handling
  target: remove transport_complete
  pscsi: finish cmd processing from pscsi_req_done
  tcmu: fix sense handling during completion
  target: add helper to copy sense to se_cmd buffer
  target: do not require a transport_complete for SCF_TRANSPORT_TASK_SENSE
  target: make device_mutex and device_list static
  tcmu: Fix flushing cmd entry dcache page
  tcmu: fix multiple uio open/close sequences
  tcmu: drop configured check in destroy
  ...
parents 62403005 138d351e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1452,7 +1452,7 @@ static void
isert_login_recv_done(struct ib_cq *cq, struct ib_wc *wc)
{
	struct isert_conn *isert_conn = wc->qp->qp_context;
	struct ib_device *ib_dev = isert_conn->cm_id->device;
	struct ib_device *ib_dev = isert_conn->device->ib_device;

	if (unlikely(wc->status != IB_WC_SUCCESS)) {
		isert_print_wc(wc, "login recv");
+2 −2
Original line number Diff line number Diff line
@@ -1157,8 +1157,8 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
	}
	spin_unlock_irqrestore(&ioctx->spinlock, flags);

	pr_debug("Aborting cmd with state %d and tag %lld\n", state,
		 ioctx->cmd.tag);
	pr_debug("Aborting cmd with state %d -> %d and tag %lld\n", state,
		 ioctx->state, ioctx->cmd.tag);

	switch (state) {
	case SRPT_STATE_NEW:
+143 −13
Original line number Diff line number Diff line
@@ -155,6 +155,9 @@ static long ibmvscsis_unregister_command_q(struct scsi_info *vscsi)
		qrc = h_free_crq(vscsi->dds.unit_id);
		switch (qrc) {
		case H_SUCCESS:
			spin_lock_bh(&vscsi->intr_lock);
			vscsi->flags &= ~PREP_FOR_SUSPEND_FLAGS;
			spin_unlock_bh(&vscsi->intr_lock);
			break;

		case H_HARDWARE:
@@ -422,6 +425,9 @@ static void ibmvscsis_disconnect(struct work_struct *work)
	new_state = vscsi->new_state;
	vscsi->new_state = 0;

	vscsi->flags |= DISCONNECT_SCHEDULED;
	vscsi->flags &= ~SCHEDULE_DISCONNECT;

	pr_debug("disconnect: flags 0x%x, state 0x%hx\n", vscsi->flags,
		 vscsi->state);

@@ -802,6 +808,13 @@ static long ibmvscsis_establish_new_q(struct scsi_info *vscsi)
	long rc = ADAPT_SUCCESS;
	uint format;

	rc = h_vioctl(vscsi->dds.unit_id, H_ENABLE_PREPARE_FOR_SUSPEND, 30000,
		      0, 0, 0, 0);
	if (rc == H_SUCCESS)
		vscsi->flags |= PREP_FOR_SUSPEND_ENABLED;
	else if (rc != H_NOT_FOUND)
		pr_err("Error from Enable Prepare for Suspend: %ld\n", rc);

	vscsi->flags &= PRESERVE_FLAG_FIELDS;
	vscsi->rsp_q_timer.timer_pops = 0;
	vscsi->debit = 0;
@@ -950,6 +963,63 @@ static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi,
	}
}

/**
 * ibmvscsis_ready_for_suspend() - Helper function to call VIOCTL
 * @vscsi:	Pointer to our adapter structure
 * @idle:	Indicates whether we were called from adapter_idle.  This
 *		is important to know if we need to do a disconnect, since if
 *		we're called from adapter_idle, we're still processing the
 *		current disconnect, so we can't just call post_disconnect.
 *
 * This function is called when the adapter is idle when phyp has sent
 * us a Prepare for Suspend Transport Event.
 *
 * EXECUTION ENVIRONMENT:
 *	Process or interrupt environment called with interrupt lock held
 */
static long ibmvscsis_ready_for_suspend(struct scsi_info *vscsi, bool idle)
{
	long rc = 0;
	struct viosrp_crq *crq;

	/* See if there is a Resume event in the queue */
	crq = vscsi->cmd_q.base_addr + vscsi->cmd_q.index;

	pr_debug("ready_suspend: flags 0x%x, state 0x%hx crq_valid:%x\n",
		 vscsi->flags, vscsi->state, (int)crq->valid);

	if (!(vscsi->flags & PREP_FOR_SUSPEND_ABORTED) && !(crq->valid)) {
		rc = h_vioctl(vscsi->dds.unit_id, H_READY_FOR_SUSPEND, 0, 0, 0,
			      0, 0);
		if (rc) {
			pr_err("Ready for Suspend Vioctl failed: %ld\n", rc);
			rc = 0;
		}
	} else if (((vscsi->flags & PREP_FOR_SUSPEND_OVERWRITE) &&
		    (vscsi->flags & PREP_FOR_SUSPEND_ABORTED)) ||
		   ((crq->valid) && ((crq->valid != VALID_TRANS_EVENT) ||
				     (crq->format != RESUME_FROM_SUSP)))) {
		if (idle) {
			vscsi->state = ERR_DISCONNECT_RECONNECT;
			ibmvscsis_reset_queue(vscsi);
			rc = -1;
		} else if (vscsi->state == CONNECTED) {
			ibmvscsis_post_disconnect(vscsi,
						  ERR_DISCONNECT_RECONNECT, 0);
		}

		vscsi->flags &= ~PREP_FOR_SUSPEND_OVERWRITE;

		if ((crq->valid) && ((crq->valid != VALID_TRANS_EVENT) ||
				     (crq->format != RESUME_FROM_SUSP)))
			pr_err("Invalid element in CRQ after Prepare for Suspend");
	}

	vscsi->flags &= ~(PREP_FOR_SUSPEND_PENDING | PREP_FOR_SUSPEND_ABORTED);

	return rc;
}

/**
 * ibmvscsis_trans_event() - Handle a Transport Event
 * @vscsi:	Pointer to our adapter structure
@@ -974,18 +1044,8 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi,
	case PARTNER_FAILED:
	case PARTNER_DEREGISTER:
		ibmvscsis_delete_client_info(vscsi, true);
		break;

	default:
		rc = ERROR;
		dev_err(&vscsi->dev, "trans_event: invalid format %d\n",
			(uint)crq->format);
		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT,
					  RESPONSE_Q_DOWN);
		break;
	}

	if (rc == ADAPT_SUCCESS) {
		if (crq->format == MIGRATED)
			vscsi->flags &= ~PREP_FOR_SUSPEND_OVERWRITE;
		switch (vscsi->state) {
		case NO_QUEUE:
		case ERR_DISCONNECTED:
@@ -1034,6 +1094,60 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi,
			vscsi->flags |= (RESPONSE_Q_DOWN | TRANS_EVENT);
			break;
		}
		break;

	case PREPARE_FOR_SUSPEND:
		pr_debug("Prep for Suspend, crq status = 0x%x\n",
			 (int)crq->status);
		switch (vscsi->state) {
		case ERR_DISCONNECTED:
		case WAIT_CONNECTION:
		case CONNECTED:
			ibmvscsis_ready_for_suspend(vscsi, false);
			break;
		case SRP_PROCESSING:
			vscsi->resume_state = vscsi->state;
			vscsi->flags |= PREP_FOR_SUSPEND_PENDING;
			if (crq->status == CRQ_ENTRY_OVERWRITTEN)
				vscsi->flags |= PREP_FOR_SUSPEND_OVERWRITE;
			ibmvscsis_post_disconnect(vscsi, WAIT_IDLE, 0);
			break;
		case NO_QUEUE:
		case UNDEFINED:
		case UNCONFIGURING:
		case WAIT_ENABLED:
		case ERR_DISCONNECT:
		case ERR_DISCONNECT_RECONNECT:
		case WAIT_IDLE:
			pr_err("Invalid state for Prepare for Suspend Trans Event: 0x%x\n",
			       vscsi->state);
			break;
		}
		break;

	case RESUME_FROM_SUSP:
		pr_debug("Resume from Suspend, crq status = 0x%x\n",
			 (int)crq->status);
		if (vscsi->flags & PREP_FOR_SUSPEND_PENDING) {
			vscsi->flags |= PREP_FOR_SUSPEND_ABORTED;
		} else {
			if ((crq->status == CRQ_ENTRY_OVERWRITTEN) ||
			    (vscsi->flags & PREP_FOR_SUSPEND_OVERWRITE)) {
				ibmvscsis_post_disconnect(vscsi,
							  ERR_DISCONNECT_RECONNECT,
							  0);
				vscsi->flags &= ~PREP_FOR_SUSPEND_OVERWRITE;
			}
		}
		break;

	default:
		rc = ERROR;
		dev_err(&vscsi->dev, "trans_event: invalid format %d\n",
			(uint)crq->format);
		ibmvscsis_post_disconnect(vscsi, ERR_DISCONNECT,
					  RESPONSE_Q_DOWN);
		break;
	}

	rc = vscsi->flags & SCHEDULE_DISCONNECT;
@@ -1201,6 +1315,7 @@ static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi)
static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)
{
	int free_qs = false;
	long rc = 0;

	pr_debug("adapter_idle: flags 0x%x, state 0x%hx\n", vscsi->flags,
		 vscsi->state);
@@ -1240,7 +1355,14 @@ static void ibmvscsis_adapter_idle(struct scsi_info *vscsi)
		vscsi->rsp_q_timer.timer_pops = 0;
		vscsi->debit = 0;
		vscsi->credit = 0;
		if (vscsi->flags & TRANS_EVENT) {
		if (vscsi->flags & PREP_FOR_SUSPEND_PENDING) {
			vscsi->state = vscsi->resume_state;
			vscsi->resume_state = 0;
			rc = ibmvscsis_ready_for_suspend(vscsi, true);
			vscsi->flags &= ~DISCONNECT_SCHEDULED;
			if (rc)
				break;
		} else if (vscsi->flags & TRANS_EVENT) {
			vscsi->state = WAIT_CONNECTION;
			vscsi->flags &= PRESERVE_FLAG_FIELDS;
		} else {
@@ -3792,8 +3914,16 @@ static struct se_portal_group *ibmvscsis_make_tpg(struct se_wwn *wwn,
{
	struct ibmvscsis_tport *tport =
		container_of(wwn, struct ibmvscsis_tport, tport_wwn);
	u16 tpgt;
	int rc;

	if (strstr(name, "tpgt_") != name)
		return ERR_PTR(-EINVAL);
	rc = kstrtou16(name + 5, 0, &tpgt);
	if (rc)
		return ERR_PTR(rc);
	tport->tport_tpgt = tpgt;

	tport->releasing = false;

	rc = core_tpg_register(&tport->tport_wwn, &tport->se_tpg,
+23 −2
Original line number Diff line number Diff line
@@ -262,6 +262,14 @@ struct scsi_info {
#define DISCONNECT_SCHEDULED          0x00800
	/* remove function is sleeping */
#define CFG_SLEEPING                  0x01000
	/* Register for Prepare for Suspend Transport Events */
#define PREP_FOR_SUSPEND_ENABLED      0x02000
	/* Prepare for Suspend event sent */
#define PREP_FOR_SUSPEND_PENDING      0x04000
	/* Resume from Suspend event sent */
#define PREP_FOR_SUSPEND_ABORTED      0x08000
	/* Prepare for Suspend event overwrote another CRQ entry */
#define PREP_FOR_SUSPEND_OVERWRITE    0x10000
	u32 flags;
	/* adapter lock */
	spinlock_t intr_lock;
@@ -272,6 +280,7 @@ struct scsi_info {
	/* used in crq, to tag what iu the response is for */
	u64  empty_iu_tag;
	uint new_state;
	uint resume_state;
	/* control block for the response queue timer */
	struct timer_cb rsp_q_timer;
	/* keep last client to enable proper accounting */
@@ -324,8 +333,13 @@ struct scsi_info {
#define TARGET_STOP(VSCSI) (long)(((VSCSI)->state & DONT_PROCESS_STATE) | \
				  ((VSCSI)->flags & BLOCK))

#define PREP_FOR_SUSPEND_FLAGS  (PREP_FOR_SUSPEND_ENABLED | \
				 PREP_FOR_SUSPEND_PENDING | \
				 PREP_FOR_SUSPEND_ABORTED | \
				 PREP_FOR_SUSPEND_OVERWRITE)

/* flag bit that are not reset during disconnect */
#define PRESERVE_FLAG_FIELDS 0
#define PRESERVE_FLAG_FIELDS (PREP_FOR_SUSPEND_FLAGS)

#define vio_iu(IUE) ((union viosrp_iu *)((IUE)->sbuf->buf))

@@ -335,6 +349,13 @@ struct scsi_info {
#ifndef H_GET_PARTNER_INFO
#define H_GET_PARTNER_INFO              0x0000000000000008LL
#endif
#ifndef H_ENABLE_PREPARE_FOR_SUSPEND
#define H_ENABLE_PREPARE_FOR_SUSPEND    0x000000000000001DLL
#endif
#ifndef H_READY_FOR_SUSPEND
#define H_READY_FOR_SUSPEND             0x000000000000001ELL
#endif


#define h_copy_rdma(l, sa, sb, da, db) \
		plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db)
+4 −1
Original line number Diff line number Diff line
@@ -30,10 +30,13 @@ enum srp_trans_event {
	UNUSED_FORMAT = 0,
	PARTNER_FAILED = 1,
	PARTNER_DEREGISTER = 2,
	MIGRATED = 6
	MIGRATED = 6,
	PREPARE_FOR_SUSPEND = 9,
	RESUME_FROM_SUSP = 0xA
};

enum srp_status {
	CRQ_ENTRY_OVERWRITTEN = 0x20,
	HEADER_DESCRIPTOR = 0xF1,
	PING = 0xF5,
	PING_RESPONSE = 0xF6
Loading