Fix multiple problems around LUN disable under load.
- Move private data about ATIOs/INOTs from per-LUN to per-channel data. This allows active commands to continue operation after LUN destruction. This also simplifies lookup of the data by tag in some situations. - Unify three restart_queue processing implementations. - Complete all ATIOs from restart_queue on LUN disable. - Delete ATIO private data when command completed or aborted, not depending on the ATIO being requeued, that was ugly hack and could never happen. CAM should always call ether XPT_CONT_TARGET_IO with status or XPT_ABORT. - Implement XPT_ABORT for queued ATIOs/INOTs to allow CAM do graceful shutdown, not depending on LUN disable, as it is done in ahd(4)/targ(4). - Unify isp_endcmd() arguments to make it more usable in generic code. - Remove never really used LUN state reference counter. MFC after: 2 weeks
This commit is contained in:
parent
b28a6ab3bd
commit
8290ea90be
File diff suppressed because it is too large
Load Diff
@ -100,7 +100,7 @@ typedef struct atio_private_data {
|
|||||||
uint32_t bytes_xfered;
|
uint32_t bytes_xfered;
|
||||||
uint32_t bytes_in_transit;
|
uint32_t bytes_in_transit;
|
||||||
uint32_t tag; /* typically f/w RX_ID */
|
uint32_t tag; /* typically f/w RX_ID */
|
||||||
uint32_t lun;
|
lun_id_t lun;
|
||||||
uint32_t nphdl;
|
uint32_t nphdl;
|
||||||
uint32_t sid;
|
uint32_t sid;
|
||||||
uint32_t portid;
|
uint32_t portid;
|
||||||
@ -139,14 +139,12 @@ typedef struct atio_private_data {
|
|||||||
#define ATPD_GET_SEQNO(hdrp) (((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_MASK)
|
#define ATPD_GET_SEQNO(hdrp) (((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_MASK)
|
||||||
#define ATPD_GET_NCAM(hdrp) ((((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0)
|
#define ATPD_GET_NCAM(hdrp) ((((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0)
|
||||||
|
|
||||||
typedef union inot_private_data inot_private_data_t;
|
typedef struct inot_private_data inot_private_data_t;
|
||||||
union inot_private_data {
|
struct inot_private_data {
|
||||||
inot_private_data_t *next;
|
STAILQ_ENTRY(inot_private_data) next;
|
||||||
struct {
|
isp_notify_t nt;
|
||||||
isp_notify_t nt; /* must be first! */
|
uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
|
||||||
uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
|
uint32_t tag_id, seq_id;
|
||||||
uint32_t tag_id, seq_id;
|
|
||||||
} rd;
|
|
||||||
};
|
};
|
||||||
typedef struct isp_timed_notify_ack {
|
typedef struct isp_timed_notify_ack {
|
||||||
void *isp;
|
void *isp;
|
||||||
@ -155,21 +153,15 @@ typedef struct isp_timed_notify_ack {
|
|||||||
struct callout timer;
|
struct callout timer;
|
||||||
} isp_tna_t;
|
} isp_tna_t;
|
||||||
|
|
||||||
|
STAILQ_HEAD(ntpdlist, inot_private_data);
|
||||||
typedef struct tstate {
|
typedef struct tstate {
|
||||||
SLIST_ENTRY(tstate) next;
|
SLIST_ENTRY(tstate) next;
|
||||||
lun_id_t ts_lun;
|
lun_id_t ts_lun;
|
||||||
struct cam_path *owner;
|
struct ccb_hdr_slist atios;
|
||||||
struct ccb_hdr_slist atios;
|
struct ccb_hdr_slist inots;
|
||||||
struct ccb_hdr_slist inots;
|
struct ntpdlist restart_queue;
|
||||||
uint32_t hold;
|
|
||||||
uint16_t atio_count;
|
uint16_t atio_count;
|
||||||
uint16_t inot_count;
|
uint16_t inot_count;
|
||||||
inot_private_data_t * restart_queue;
|
|
||||||
inot_private_data_t * ntfree;
|
|
||||||
inot_private_data_t ntpool[ATPDPSIZE];
|
|
||||||
LIST_HEAD(, atio_private_data) atfree;
|
|
||||||
LIST_HEAD(, atio_private_data) atused[ATPDPHASHSIZE];
|
|
||||||
atio_private_data_t atpool[ATPDPSIZE];
|
|
||||||
} tstate_t;
|
} tstate_t;
|
||||||
|
|
||||||
#define LUN_HASH_SIZE 32
|
#define LUN_HASH_SIZE 32
|
||||||
@ -211,6 +203,7 @@ struct isp_nexus {
|
|||||||
*/
|
*/
|
||||||
SLIST_HEAD(tslist, tstate);
|
SLIST_HEAD(tslist, tstate);
|
||||||
TAILQ_HEAD(isp_ccbq, ccb_hdr);
|
TAILQ_HEAD(isp_ccbq, ccb_hdr);
|
||||||
|
LIST_HEAD(atpdlist, atio_private_data);
|
||||||
|
|
||||||
struct isp_fc {
|
struct isp_fc {
|
||||||
struct cam_sim *sim;
|
struct cam_sim *sim;
|
||||||
@ -242,6 +235,11 @@ struct isp_fc {
|
|||||||
#ifdef ISP_TARGET_MODE
|
#ifdef ISP_TARGET_MODE
|
||||||
struct tslist lun_hash[LUN_HASH_SIZE];
|
struct tslist lun_hash[LUN_HASH_SIZE];
|
||||||
struct isp_ccbq waitq; /* waiting CCBs */
|
struct isp_ccbq waitq; /* waiting CCBs */
|
||||||
|
struct ntpdlist ntfree;
|
||||||
|
inot_private_data_t ntpool[ATPDPSIZE];
|
||||||
|
struct atpdlist atfree;
|
||||||
|
struct atpdlist atused[ATPDPHASHSIZE];
|
||||||
|
atio_private_data_t atpool[ATPDPSIZE];
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
unsigned int inject_lost_data_frame;
|
unsigned int inject_lost_data_frame;
|
||||||
#endif
|
#endif
|
||||||
@ -258,6 +256,11 @@ struct isp_spi {
|
|||||||
#ifdef ISP_TARGET_MODE
|
#ifdef ISP_TARGET_MODE
|
||||||
struct tslist lun_hash[LUN_HASH_SIZE];
|
struct tslist lun_hash[LUN_HASH_SIZE];
|
||||||
struct isp_ccbq waitq; /* waiting CCBs */
|
struct isp_ccbq waitq; /* waiting CCBs */
|
||||||
|
struct ntpdlist ntfree;
|
||||||
|
inot_private_data_t ntpool[ATPDPSIZE];
|
||||||
|
struct atpdlist atfree;
|
||||||
|
struct atpdlist atused[ATPDPHASHSIZE];
|
||||||
|
atio_private_data_t atpool[ATPDPSIZE];
|
||||||
#endif
|
#endif
|
||||||
int num_threads;
|
int num_threads;
|
||||||
};
|
};
|
||||||
|
@ -503,11 +503,11 @@ isp_endcmd(ispsoftc_t *isp, ...)
|
|||||||
ct7_entry_t _ctio7;
|
ct7_entry_t _ctio7;
|
||||||
} un;
|
} un;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
int vpidx, nphdl;
|
||||||
|
|
||||||
ISP_MEMZERO(&un, sizeof un);
|
ISP_MEMZERO(&un, sizeof un);
|
||||||
|
|
||||||
if (IS_24XX(isp)) {
|
if (IS_24XX(isp)) {
|
||||||
int vpidx, nphdl;
|
|
||||||
at7_entry_t *aep;
|
at7_entry_t *aep;
|
||||||
ct7_entry_t *cto = &un._ctio7;
|
ct7_entry_t *cto = &un._ctio7;
|
||||||
|
|
||||||
@ -573,6 +573,9 @@ isp_endcmd(ispsoftc_t *isp, ...)
|
|||||||
|
|
||||||
va_start(ap, isp);
|
va_start(ap, isp);
|
||||||
aep = va_arg(ap, at2_entry_t *);
|
aep = va_arg(ap, at2_entry_t *);
|
||||||
|
/* nphdl and vpidx are unused here. */
|
||||||
|
nphdl = va_arg(ap, int);
|
||||||
|
vpidx = va_arg(ap, int);
|
||||||
code = va_arg(ap, uint32_t);
|
code = va_arg(ap, uint32_t);
|
||||||
hdl = va_arg(ap, uint32_t);
|
hdl = va_arg(ap, uint32_t);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user