Print this page
NEX-6018 Return of the walking dead idm_refcnt_wait_ref comstar threads
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5428 Backout the 5.0 changes
NEX-2937 Continuous write_same starves all other commands
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-3622 COMSTAR should have per remote port kstats for I/O and latency
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-3169 STMF has duplicate code in 6 places which is error prone.
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewby by: Steve Ping <steve.ping@nexenta.com>
Re #6790 backspace should perform delete on console
VAAI (XXX ATS support for COMSTAR, YYY Block-copy support for COMSTAR)
*** 18,27 ****
--- 18,29 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
#ifndef _STMF_IMPL_H
#define _STMF_IMPL_H
*** 87,97 ****
uint32_t ilu_task_cntr2;
uint32_t *ilu_cur_task_cntr;
uint32_t ilu_ntasks; /* # of tasks in the ilu_task list */
uint32_t ilu_ntasks_free; /* # of tasks that are free */
uint32_t ilu_ntasks_min_free; /* # minimal free tasks */
! uint32_t rsvd1;
uint32_t ilu_proxy_registered;
uint64_t ilu_reg_msgid;
struct stmf_i_scsi_task *ilu_tasks;
struct stmf_i_scsi_task *ilu_free_tasks;
struct stmf_itl_data *ilu_itl_list;
--- 89,99 ----
uint32_t ilu_task_cntr2;
uint32_t *ilu_cur_task_cntr;
uint32_t ilu_ntasks; /* # of tasks in the ilu_task list */
uint32_t ilu_ntasks_free; /* # of tasks that are free */
uint32_t ilu_ntasks_min_free; /* # minimal free tasks */
! uint32_t ilu_additional_ref;
uint32_t ilu_proxy_registered;
uint64_t ilu_reg_msgid;
struct stmf_i_scsi_task *ilu_tasks;
struct stmf_i_scsi_task *ilu_free_tasks;
struct stmf_itl_data *ilu_itl_list;
*** 162,171 ****
--- 164,185 ----
struct scsi_devid_desc *irport_id;
kmutex_t irport_mutex;
int irport_refcnt;
id_t irport_instance;
avl_node_t irport_ln;
+ /* number of active read tasks */
+ uint32_t irport_nread_tasks;
+ /* number of active write tasks */
+ uint32_t irport_nwrite_tasks;
+ hrtime_t irport_rdstart_timestamp;
+ hrtime_t irport_rddone_timestamp;
+ hrtime_t irport_wrstart_timestamp;
+ hrtime_t irport_wrdone_timestamp;
+ kstat_t *irport_kstat_info;
+ kstat_t *irport_kstat_io;
+ kstat_t *irport_kstat_estat; /* extended stats */
+ boolean_t irport_info_dirty;
} stmf_i_remote_port_t;
/*
* ilport flags
*/
*** 235,253 ****
struct stmf_worker;
typedef struct stmf_i_scsi_task {
scsi_task_t *itask_task;
uint32_t itask_alloc_size;
uint32_t itask_flags;
uint64_t itask_proxy_msg_id;
stmf_data_buf_t *itask_proxy_dbuf;
struct stmf_worker *itask_worker;
uint32_t *itask_ilu_task_cntr;
struct stmf_i_scsi_task *itask_worker_next;
struct stmf_i_scsi_task *itask_lu_next;
struct stmf_i_scsi_task *itask_lu_prev;
struct stmf_i_scsi_task *itask_lu_free_next;
- struct stmf_i_scsi_task *itask_abort_next;
struct stmf_itl_data *itask_itl_datap;
clock_t itask_start_time; /* abort and normal */
/* For now we only support 4 parallel buffers. Should be enough. */
stmf_data_buf_t *itask_dbufs[4];
clock_t itask_poll_timeout;
--- 249,267 ----
struct stmf_worker;
typedef struct stmf_i_scsi_task {
scsi_task_t *itask_task;
uint32_t itask_alloc_size;
uint32_t itask_flags;
+ kmutex_t itask_mutex; /* protects flags and lists */
uint64_t itask_proxy_msg_id;
stmf_data_buf_t *itask_proxy_dbuf;
struct stmf_worker *itask_worker;
uint32_t *itask_ilu_task_cntr;
struct stmf_i_scsi_task *itask_worker_next;
struct stmf_i_scsi_task *itask_lu_next;
struct stmf_i_scsi_task *itask_lu_prev;
struct stmf_i_scsi_task *itask_lu_free_next;
struct stmf_itl_data *itask_itl_datap;
clock_t itask_start_time; /* abort and normal */
/* For now we only support 4 parallel buffers. Should be enough. */
stmf_data_buf_t *itask_dbufs[4];
clock_t itask_poll_timeout;
*** 257,266 ****
--- 271,281 ----
uint16_t itask_cdb_buf_size;
/* Task profile data */
hrtime_t itask_start_timestamp;
hrtime_t itask_done_timestamp;
+ hrtime_t itask_xfer_done_timestamp;
hrtime_t itask_waitq_enter_timestamp;
hrtime_t itask_waitq_time;
hrtime_t itask_lu_read_time;
hrtime_t itask_lu_write_time;
hrtime_t itask_lport_read_time;
*** 273,282 ****
--- 288,332 ----
} stmf_i_scsi_task_t;
#define ITASK_DEFAULT_ABORT_TIMEOUT 5
/*
+ * Common code to encode an itask onto the worker_task queue is placed
+ * in this macro to simplify future maintenace activity.
+ */
+ #define STMF_ENQUEUE_ITASK(w, i) \
+ ASSERT((itask->itask_flags & ITASK_IN_FREE_LIST) == 0); \
+ ASSERT(mutex_owned(&itask->itask_mutex)); \
+ ASSERT(mutex_owned(&w->worker_lock)); \
+ i->itask_worker_next = NULL; \
+ if (w->worker_task_tail) { \
+ w->worker_task_tail->itask_worker_next = i; \
+ } else { \
+ w->worker_task_head = i; \
+ } \
+ w->worker_task_tail = i; \
+ if (++(w->worker_queue_depth) > w->worker_max_qdepth_pu) { \
+ w->worker_max_qdepth_pu = w->worker_queue_depth; \
+ } \
+ atomic_inc_32(&w->worker_ref_count); \
+ atomic_or_32(&itask->itask_flags, ITASK_IN_WORKER_QUEUE); \
+ i->itask_waitq_enter_timestamp = gethrtime(); \
+ if ((w->worker_flags & STMF_WORKER_ACTIVE) == 0) \
+ cv_signal(&w->worker_cv);
+
+ #define STMF_DEQUEUE_ITASK(w, itask) \
+ ASSERT(mutex_owned(&w->worker_lock)); \
+ if ((itask = w->worker_task_head) != NULL) { \
+ w->worker_task_head = itask->itask_worker_next; \
+ if (w->worker_task_head == NULL) { \
+ w->worker_task_tail = NULL; \
+ } \
+ } else { \
+ w->worker_task_tail = NULL; \
+ }
+
+ /*
* itask_flags
*/
#define ITASK_IN_FREE_LIST 0x0001
#define ITASK_IN_TRANSITION 0x0002
#define ITASK_IN_WORKER_QUEUE 0x0004