scsi: target: tcmu: Implement tmr_notify callback
This patch implements the tmr_notify callback for tcmu. When the callback is called, tcmu checks the list of aborted commands it received as parameter: - aborted commands in the qfull_queue are removed from the queue and target_complete_command is called - from the cmd_ids of aborted commands currently uncompleted in cmd ring it creates a list of aborted cmd_ids. Finally a TMR notification is written to cmd ring containing TMR type and cmd_id list. If there is no space in ring, the TMR notification is queued on a TMR specific queue. The TMR specific queue 'tmr_queue' can be seen as a extension of the cmd ring. At the end of each iexecution of tcmu_complete_commands() we check whether tmr_queue contains TMRs and try to move them onto the ring. If tmr_queue is not empty after that, we don't call run_qfull_queue() because commands must not overtake TMRs. This way we guarantee that cmd_ids in TMR notification received by userspace either match an active, not yet completed command or are no longer valid due to userspace having complete some cmd_ids meanwhile. New commands that were assigned to an aborted cmd_id will always appear on the cmd ring _after_ the TMR. Link: https://lore.kernel.org/r/20200726153510.13077-8-bstroesser@ts.fujitsu.com Reviewed-by: Mike Christie <michael.christie@oracle.com> Signed-off-by: Bodo Stroesser <bstroesser@ts.fujitsu.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
ed212ca878
commit
bc2d214af5
@@ -45,6 +45,7 @@
|
||||
#define ALIGN_SIZE 64 /* Should be enough for most CPUs */
|
||||
#define TCMU_MAILBOX_FLAG_CAP_OOOC (1 << 0) /* Out-of-order completions */
|
||||
#define TCMU_MAILBOX_FLAG_CAP_READ_LEN (1 << 1) /* Read data length */
|
||||
#define TCMU_MAILBOX_FLAG_CAP_TMR (1 << 2) /* TMR notifications */
|
||||
|
||||
struct tcmu_mailbox {
|
||||
__u16 version;
|
||||
@@ -62,6 +63,7 @@ struct tcmu_mailbox {
|
||||
enum tcmu_opcode {
|
||||
TCMU_OP_PAD = 0,
|
||||
TCMU_OP_CMD,
|
||||
TCMU_OP_TMR,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -128,6 +130,29 @@ struct tcmu_cmd_entry {
|
||||
|
||||
} __packed;
|
||||
|
||||
struct tcmu_tmr_entry {
|
||||
struct tcmu_cmd_entry_hdr hdr;
|
||||
|
||||
#define TCMU_TMR_UNKNOWN 0
|
||||
#define TCMU_TMR_ABORT_TASK 1
|
||||
#define TCMU_TMR_ABORT_TASK_SET 2
|
||||
#define TCMU_TMR_CLEAR_ACA 3
|
||||
#define TCMU_TMR_CLEAR_TASK_SET 4
|
||||
#define TCMU_TMR_LUN_RESET 5
|
||||
#define TCMU_TMR_TARGET_WARM_RESET 6
|
||||
#define TCMU_TMR_TARGET_COLD_RESET 7
|
||||
/* Pseudo reset due to received PR OUT */
|
||||
#define TCMU_TMR_LUN_RESET_PRO 128
|
||||
__u8 tmr_type;
|
||||
|
||||
__u8 __pad1;
|
||||
__u16 __pad2;
|
||||
__u32 cmd_cnt;
|
||||
__u64 __pad3;
|
||||
__u64 __pad4;
|
||||
__u16 cmd_ids[0];
|
||||
} __packed;
|
||||
|
||||
#define TCMU_OP_ALIGN_SIZE sizeof(__u64)
|
||||
|
||||
enum tcmu_genl_cmd {
|
||||
|
||||
Reference in New Issue
Block a user