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_in_transit;
|
||||
uint32_t tag; /* typically f/w RX_ID */
|
||||
uint32_t lun;
|
||||
lun_id_t lun;
|
||||
uint32_t nphdl;
|
||||
uint32_t sid;
|
||||
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_NCAM(hdrp) ((((isphdr_t *)hdrp)->rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0)
|
||||
|
||||
typedef union inot_private_data inot_private_data_t;
|
||||
union inot_private_data {
|
||||
inot_private_data_t *next;
|
||||
struct {
|
||||
isp_notify_t nt; /* must be first! */
|
||||
uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
|
||||
uint32_t tag_id, seq_id;
|
||||
} rd;
|
||||
typedef struct inot_private_data inot_private_data_t;
|
||||
struct inot_private_data {
|
||||
STAILQ_ENTRY(inot_private_data) next;
|
||||
isp_notify_t nt;
|
||||
uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */
|
||||
uint32_t tag_id, seq_id;
|
||||
};
|
||||
typedef struct isp_timed_notify_ack {
|
||||
void *isp;
|
||||
@ -155,21 +153,15 @@ typedef struct isp_timed_notify_ack {
|
||||
struct callout timer;
|
||||
} isp_tna_t;
|
||||
|
||||
STAILQ_HEAD(ntpdlist, inot_private_data);
|
||||
typedef struct tstate {
|
||||
SLIST_ENTRY(tstate) next;
|
||||
lun_id_t ts_lun;
|
||||
struct cam_path *owner;
|
||||
struct ccb_hdr_slist atios;
|
||||
struct ccb_hdr_slist inots;
|
||||
uint32_t hold;
|
||||
SLIST_ENTRY(tstate) next;
|
||||
lun_id_t ts_lun;
|
||||
struct ccb_hdr_slist atios;
|
||||
struct ccb_hdr_slist inots;
|
||||
struct ntpdlist restart_queue;
|
||||
uint16_t atio_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;
|
||||
|
||||
#define LUN_HASH_SIZE 32
|
||||
@ -211,6 +203,7 @@ struct isp_nexus {
|
||||
*/
|
||||
SLIST_HEAD(tslist, tstate);
|
||||
TAILQ_HEAD(isp_ccbq, ccb_hdr);
|
||||
LIST_HEAD(atpdlist, atio_private_data);
|
||||
|
||||
struct isp_fc {
|
||||
struct cam_sim *sim;
|
||||
@ -242,6 +235,11 @@ struct isp_fc {
|
||||
#ifdef ISP_TARGET_MODE
|
||||
struct tslist lun_hash[LUN_HASH_SIZE];
|
||||
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)
|
||||
unsigned int inject_lost_data_frame;
|
||||
#endif
|
||||
@ -258,6 +256,11 @@ struct isp_spi {
|
||||
#ifdef ISP_TARGET_MODE
|
||||
struct tslist lun_hash[LUN_HASH_SIZE];
|
||||
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
|
||||
int num_threads;
|
||||
};
|
||||
|
@ -503,11 +503,11 @@ isp_endcmd(ispsoftc_t *isp, ...)
|
||||
ct7_entry_t _ctio7;
|
||||
} un;
|
||||
va_list ap;
|
||||
int vpidx, nphdl;
|
||||
|
||||
ISP_MEMZERO(&un, sizeof un);
|
||||
|
||||
if (IS_24XX(isp)) {
|
||||
int vpidx, nphdl;
|
||||
at7_entry_t *aep;
|
||||
ct7_entry_t *cto = &un._ctio7;
|
||||
|
||||
@ -573,6 +573,9 @@ isp_endcmd(ispsoftc_t *isp, ...)
|
||||
|
||||
va_start(ap, isp);
|
||||
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);
|
||||
hdl = va_arg(ap, uint32_t);
|
||||
va_end(ap);
|
||||
|
Loading…
Reference in New Issue
Block a user