Print this page
3862 stmf + kstat = kernel panic
3863 stmf_itl_task_start() must check for ilu->ilu_kstat_io is non-null
3864 memory leak in the iSCSI code
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Richard Elling <richard.elling@gmail.com>
Approved by: Gordon Ross <gwr@nexenta.com>
3621 ZFS LU stuck in the offlining state
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Jeff Biseda <jeff.biseda@delphix.com>
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Approved by: Christopher Siden <christopher.siden@delphix.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/comstar/stmf/stmf_impl.h
+++ new/usr/src/uts/common/io/comstar/stmf/stmf_impl.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23 + * Copyright (c) 2013 by Delphix. All rights reserved.
23 24 */
24 25 #ifndef _STMF_IMPL_H
25 26 #define _STMF_IMPL_H
26 27
27 28 #include <sys/stmf_defines.h>
28 29 #include <sys/stmf_ioctl.h>
29 30
30 31 #ifdef __cplusplus
31 32 extern "C" {
32 33 #endif
33 34
34 35 typedef uint32_t stmf_event_handle_t;
35 36 #define STMF_MAX_NUM_EVENTS (sizeof (stmf_event_handle_t) * 8)
36 37 #define STMF_EVENT_ADD(h, e) (atomic_or_32(&(h), \
37 38 ((uint32_t)1) << (e)))
38 39 #define STMF_EVENT_REMOVE(h, e) (atomic_and_32(&(h), \
39 40 ~(((uint32_t)1) << (e))))
40 41 #define STMF_EVENT_ENABLED(h, e) (((h) & ((uint32_t)1) << (e)) != 0)
41 42 #define STMF_EVENT_CLEAR_ALL(h) ((h) = 0)
42 43 #define STMF_EVENT_ALLOC_HANDLE(h) ((h) = 0)
43 44 #define STMF_EVENT_FREE_HANDLE(h) ((h) = 0)
44 45
45 46 #define STMF_TGT_NAME_LEN 256
46 47 #define STMF_GUID_INPUT 32
47 48
48 49 #define STMF_UPDATE_KSTAT_IO(kip, dbuf) \
49 50 if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { \
50 51 kip->reads++; \
51 52 kip->nread += dbuf->db_data_size; \
52 53 } else { \
53 54 kip->writes++; \
54 55 kip->nwritten += dbuf->db_data_size; \
55 56 }
56 57
57 58 struct stmf_i_scsi_task;
58 59 struct stmf_itl_data;
59 60
60 61 typedef struct stmf_i_lu_provider {
61 62 stmf_lu_provider_t *ilp_lp;
62 63 uint32_t ilp_alloc_size;
63 64 uint32_t ilp_nlus; /* # LUNs being exported */
64 65 uint32_t ilp_cb_in_progress:1,
65 66 ilp_rsvd:31;
66 67 struct stmf_i_lu_provider *ilp_next;
67 68 struct stmf_pp_data *ilp_ppd;
68 69 } stmf_i_lu_provider_t;
69 70
70 71 typedef struct stmf_i_lu {
71 72 stmf_lu_t *ilu_lu;
72 73 uint32_t ilu_alloc_size;
73 74 uint32_t ilu_flags;
74 75 uint32_t ilu_ref_cnt;
75 76 uint8_t ilu_state;
76 77 uint8_t ilu_prev_state;
77 78 uint8_t ilu_access;
78 79 uint8_t ilu_alua;
79 80 stmf_event_handle_t ilu_event_hdl;
80 81 struct stmf_i_lu *ilu_next;
81 82 struct stmf_i_lu *ilu_prev;
82 83 char *ilu_alias;
83 84 char ilu_ascii_hex_guid[STMF_GUID_INPUT + 1];
84 85 kmutex_t ilu_task_lock;
85 86 uint32_t ilu_task_cntr1;
86 87 uint32_t ilu_task_cntr2;
87 88 uint32_t *ilu_cur_task_cntr;
88 89 uint32_t ilu_ntasks; /* # of tasks in the ilu_task list */
89 90 uint32_t ilu_ntasks_free; /* # of tasks that are free */
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
90 91 uint32_t ilu_ntasks_min_free; /* # minimal free tasks */
91 92 uint32_t rsvd1;
92 93 uint32_t ilu_proxy_registered;
93 94 uint64_t ilu_reg_msgid;
94 95 struct stmf_i_scsi_task *ilu_tasks;
95 96 struct stmf_i_scsi_task *ilu_free_tasks;
96 97 struct stmf_itl_data *ilu_itl_list;
97 98 kstat_t *ilu_kstat_info;
98 99 kstat_t *ilu_kstat_io;
99 100 kmutex_t ilu_kstat_lock;
101 + kcondvar_t ilu_offline_pending_cv;
100 102
101 103 /* point to the luid entry in stmf_state.stmf_luid_list */
102 104 void *ilu_luid;
103 105 } stmf_i_lu_t;
104 106
105 107 /*
106 108 * ilu_flags
107 109 */
108 110 #define ILU_STALL_DEREGISTER 0x0001
109 111 #define ILU_RESET_ACTIVE 0x0002
110 112
111 113 typedef struct stmf_i_port_provider {
112 114 stmf_port_provider_t *ipp_pp;
113 115 uint32_t ipp_alloc_size;
114 116 uint32_t ipp_npps;
115 117 uint32_t ipp_cb_in_progress:1,
116 118 ipp_rsvd:31;
117 119 struct stmf_i_port_provider *ipp_next;
118 120 struct stmf_pp_data *ipp_ppd;
119 121 } stmf_i_port_provider_t;
120 122
121 123 #define MAX_ILPORT 0x10000
122 124
123 125 typedef struct stmf_i_local_port {
124 126 stmf_local_port_t *ilport_lport;
125 127 uint32_t ilport_alloc_size;
126 128 uint32_t ilport_nsessions;
127 129 struct stmf_i_scsi_session *ilport_ss_list;
128 130 krwlock_t ilport_lock;
129 131 struct stmf_i_local_port *ilport_next;
130 132 struct stmf_i_local_port *ilport_prev;
131 133 uint8_t ilport_state;
132 134 uint8_t ilport_prev_state;
133 135 uint8_t ilport_standby;
134 136 uint8_t ilport_alua;
135 137 uint16_t ilport_rtpid; /* relative tpid */
136 138 uint16_t ilport_proxy_registered;
137 139 uint64_t ilport_reg_msgid;
138 140 uint8_t ilport_no_standby_lu;
139 141 uint32_t ilport_unexpected_comp;
140 142 stmf_event_handle_t ilport_event_hdl;
141 143 clock_t ilport_last_online_clock;
142 144 clock_t ilport_avg_interval;
143 145 uint32_t ilport_online_times;
144 146 uint32_t ilport_flags;
145 147 kstat_t *ilport_kstat_info;
146 148 kstat_t *ilport_kstat_io;
147 149 kmutex_t ilport_kstat_lock;
148 150 char ilport_kstat_tgt_name[STMF_TGT_NAME_LEN];
149 151 /* which target group this port belongs to in stmf_state.stmf_tg_list */
150 152 void *ilport_tg;
151 153 id_t ilport_instance;
152 154 /* XXX Need something to track all the remote ports also */
153 155 } stmf_i_local_port_t;
154 156
155 157 #define STMF_AVG_ONLINE_INTERVAL (30 * drv_usectohz(1000000))
156 158
|
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
157 159 #define MAX_IRPORT 0x10000
158 160
159 161 typedef struct stmf_i_remote_port {
160 162 struct scsi_devid_desc *irport_id;
161 163 kmutex_t irport_mutex;
162 164 int irport_refcnt;
163 165 id_t irport_instance;
164 166 avl_node_t irport_ln;
165 167 } stmf_i_remote_port_t;
166 168
167 -typedef struct stmf_i_itl_kstat {
168 - char iitl_kstat_nm[KSTAT_STRLEN];
169 - char iitl_kstat_lport[STMF_TGT_NAME_LEN];
170 - char iitl_kstat_guid[STMF_GUID_INPUT + 1];
171 - char *iitl_kstat_strbuf;
172 - int iitl_kstat_strbuflen;
173 - kstat_t *iitl_kstat_info;
174 - kstat_t *iitl_kstat_taskq;
175 - kstat_t *iitl_kstat_lu_xfer;
176 - kstat_t *iitl_kstat_lport_xfer;
177 - avl_node_t iitl_kstat_ln;
178 -} stmf_i_itl_kstat_t;
179 -
180 169 /*
181 170 * ilport flags
182 171 */
183 172 #define ILPORT_FORCED_OFFLINE 0x01
184 173 #define ILPORT_SS_GOT_INITIAL_LUNS 0x02
185 174
186 175 typedef struct stmf_i_scsi_session {
187 176 stmf_scsi_session_t *iss_ss;
188 177 uint32_t iss_alloc_size;
189 178 uint32_t iss_flags;
190 179 stmf_i_remote_port_t *iss_irport;
191 180 struct stmf_i_scsi_session *iss_next;
192 181 /*
193 182 * Ideally we should maintain 2 maps. One would indicate a new map
194 183 * which will become available only upon receipt of a REPORT LUN
195 184 * cmd.
196 185 */
197 186 struct stmf_lun_map *iss_sm;
198 187 /*
199 188 * which host group the host of this session belongs to in
200 189 * stmf_state.stmf_hg_list
201 190 */
202 191 void *iss_hg;
203 192 krwlock_t *iss_lockp;
204 193 time_t iss_creation_time;
205 194 } stmf_i_scsi_session_t;
206 195
207 196 /*
208 197 * iss flags
209 198 */
210 199 #define ISS_LUN_INVENTORY_CHANGED 0x0001
211 200 #define ISS_RESET_ACTIVE 0x0002
212 201 #define ISS_BEING_CREATED 0x0004
213 202 #define ISS_GOT_INITIAL_LUNS 0x0008
214 203 #define ISS_EVENT_ACTIVE 0x0010
215 204 #define ISS_NULL_TPTID 0x0020
216 205
217 206 #define ITASK_MAX_NCMDS 14
218 207 #define ITASK_DEFAULT_POLL_TIMEOUT 0
219 208
220 209 #define ITASK_TASK_AUDIT_DEPTH 32 /* Must be a power of 2 */
221 210
222 211 typedef enum {
223 212 TE_UNDEFINED,
224 213 TE_TASK_START,
225 214 TE_XFER_START,
226 215 TE_XFER_DONE,
227 216 TE_SEND_STATUS,
228 217 TE_SEND_STATUS_DONE,
229 218 TE_TASK_FREE,
230 219 TE_TASK_ABORT,
231 220 TE_TASK_LPORT_ABORTED,
232 221 TE_TASK_LU_ABORTED,
233 222 TE_PROCESS_CMD
234 223 } task_audit_event_t;
235 224
236 225 #define CMD_OR_IOF_NA 0xffffffff
237 226
238 227 typedef struct stmf_task_audit_rec {
239 228 task_audit_event_t ta_event;
240 229 uint32_t ta_cmd_or_iof;
241 230 uint32_t ta_itask_flags;
242 231 stmf_data_buf_t *ta_dbuf;
243 232 timespec_t ta_timestamp;
244 233 } stmf_task_audit_rec_t;
245 234
246 235 struct stmf_worker;
247 236 typedef struct stmf_i_scsi_task {
248 237 scsi_task_t *itask_task;
249 238 uint32_t itask_alloc_size;
250 239 uint32_t itask_flags;
251 240 uint64_t itask_proxy_msg_id;
252 241 stmf_data_buf_t *itask_proxy_dbuf;
253 242 struct stmf_worker *itask_worker;
254 243 uint32_t *itask_ilu_task_cntr;
255 244 struct stmf_i_scsi_task *itask_worker_next;
256 245 struct stmf_i_scsi_task *itask_lu_next;
257 246 struct stmf_i_scsi_task *itask_lu_prev;
258 247 struct stmf_i_scsi_task *itask_lu_free_next;
259 248 struct stmf_i_scsi_task *itask_abort_next;
260 249 struct stmf_itl_data *itask_itl_datap;
261 250 clock_t itask_start_time; /* abort and normal */
262 251 /* For now we only support 4 parallel buffers. Should be enough. */
263 252 stmf_data_buf_t *itask_dbufs[4];
264 253 clock_t itask_poll_timeout;
265 254 uint8_t itask_cmd_stack[ITASK_MAX_NCMDS];
266 255 uint8_t itask_ncmds;
267 256 uint8_t itask_allocated_buf_map;
268 257 uint16_t itask_cdb_buf_size;
269 258
270 259 /* Task profile data */
271 260 hrtime_t itask_start_timestamp;
272 261 hrtime_t itask_done_timestamp;
273 262 hrtime_t itask_waitq_enter_timestamp;
274 263 hrtime_t itask_waitq_time;
275 264 hrtime_t itask_lu_read_time;
276 265 hrtime_t itask_lu_write_time;
277 266 hrtime_t itask_lport_read_time;
278 267 hrtime_t itask_lport_write_time;
279 268 uint64_t itask_read_xfer;
280 269 uint64_t itask_write_xfer;
281 270 kmutex_t itask_audit_mutex;
282 271 uint8_t itask_audit_index;
283 272 stmf_task_audit_rec_t itask_audit_records[ITASK_TASK_AUDIT_DEPTH];
284 273 } stmf_i_scsi_task_t;
285 274
286 275 #define ITASK_DEFAULT_ABORT_TIMEOUT 5
287 276
288 277 /*
289 278 * itask_flags
290 279 */
291 280 #define ITASK_IN_FREE_LIST 0x0001
292 281 #define ITASK_IN_TRANSITION 0x0002
293 282 #define ITASK_IN_WORKER_QUEUE 0x0004
294 283 #define ITASK_BEING_ABORTED 0x0008
295 284 #define ITASK_BEING_COMPLETED 0x0010
296 285 #define ITASK_KNOWN_TO_TGT_PORT 0x0020
297 286 #define ITASK_KNOWN_TO_LU 0x0040
298 287 #define ITASK_LU_ABORT_CALLED 0x0080
299 288 #define ITASK_TGT_PORT_ABORT_CALLED 0x0100
300 289 #define ITASK_DEFAULT_HANDLING 0x0200
301 290 #define ITASK_CAUSING_LU_RESET 0x0400
302 291 #define ITASK_CAUSING_TARGET_RESET 0x0800
303 292 #define ITASK_KSTAT_IN_RUNQ 0x1000
304 293 #define ITASK_PROXY_TASK 0x2000
305 294
306 295 /*
307 296 * itask cmds.
308 297 */
309 298 #define ITASK_CMD_MASK 0x1F
310 299 #define ITASK_CMD_BUF_NDX(cmd) (((uint8_t)(cmd)) >> 5)
311 300 #define ITASK_CMD_NEW_TASK 0x1
312 301 #define ITASK_CMD_DATA_XFER_DONE 0x2
313 302 #define ITASK_CMD_STATUS_DONE 0x3
314 303 #define ITASK_CMD_ABORT 0x4
315 304 #define ITASK_CMD_SEND_STATUS 0x5
316 305 #define ITASK_CMD_POLL 0x10
317 306 #define ITASK_CMD_POLL_LU (ITASK_CMD_POLL | 1)
|
↓ open down ↓ |
128 lines elided |
↑ open up ↑ |
318 307 #define ITASK_CMD_POLL_LPORT (ITASK_CMD_POLL | 2)
319 308
320 309 /*
321 310 * struct maintained on a per itl basis when the lu registers ITL handle.
322 311 */
323 312 typedef struct stmf_itl_data {
324 313 uint32_t itl_counter;
325 314 uint8_t itl_flags;
326 315 uint8_t itl_hdlrm_reason;
327 316 uint16_t itl_lun;
328 - char *itl_kstat_strbuf;
329 - int itl_kstat_strbuflen;
330 - kstat_t *itl_kstat_info;
331 - kstat_t *itl_kstat_taskq;
332 - kstat_t *itl_kstat_lu_xfer;
333 - kstat_t *itl_kstat_lport_xfer;
334 317 void *itl_handle;
335 318 struct stmf_i_lu *itl_ilu;
336 319 struct stmf_i_scsi_session *itl_session;
337 320 struct stmf_itl_data *itl_next;
338 321 } stmf_itl_data_t;
339 322
340 323 /*
341 324 * itl flags
342 325 */
343 326 #define STMF_ITL_BEING_TERMINATED 0x01
344 327
345 328 /*
346 329 * data structures to maintain provider private data.
347 330 */
348 331 typedef struct stmf_pp_data {
349 332 struct stmf_pp_data *ppd_next;
350 333 void *ppd_provider;
351 334 nvlist_t *ppd_nv;
352 335 uint32_t ppd_lu_provider:1,
353 336 ppd_port_provider:1,
354 337 ppd_rsvd:30;
355 338 uint32_t ppd_alloc_size;
356 339 uint64_t ppd_token;
357 340 char ppd_name[8];
358 341 } stmf_pp_data_t;
359 342
360 343 typedef struct stmf_worker {
361 344 kthread_t *worker_tid;
362 345 stmf_i_scsi_task_t *worker_task_head;
363 346 stmf_i_scsi_task_t *worker_task_tail;
364 347 stmf_i_scsi_task_t *worker_wait_head;
365 348 stmf_i_scsi_task_t *worker_wait_tail;
366 349 kmutex_t worker_lock;
367 350 kcondvar_t worker_cv;
368 351 uint32_t worker_flags;
369 352 uint32_t worker_queue_depth; /* ntasks cur queued */
370 353 uint32_t worker_max_qdepth_pu; /* maxqd / unit time */
371 354 uint32_t worker_max_sys_qdepth_pu; /* for all workers */
372 355 uint32_t worker_ref_count; /* # IOs referencing */
373 356 hrtime_t worker_signal_timestamp;
374 357 } stmf_worker_t;
375 358
376 359 /*
377 360 * worker flags
378 361 */
379 362 #define STMF_WORKER_STARTED 1
380 363 #define STMF_WORKER_ACTIVE 2
381 364 #define STMF_WORKER_TERMINATE 4
382 365
383 366 /*
384 367 * data struct for managing transfers.
385 368 */
386 369 typedef struct stmf_xfer_data {
387 370 uint32_t alloc_size; /* Including this struct */
388 371 uint32_t size_done;
389 372 uint32_t size_left;
390 373 uint8_t buf[4];
391 374 } stmf_xfer_data_t;
392 375
393 376 /*
394 377 * Define frequently used macros
395 378 */
396 379 #define TASK_TO_ITASK(x_task) \
397 380 ((stmf_i_scsi_task_t *)(x_task)->task_stmf_private)
398 381
399 382 void stmf_dlun_init();
400 383 stmf_status_t stmf_dlun_fini();
401 384 void stmf_worker_init();
402 385 stmf_status_t stmf_worker_fini();
403 386 void stmf_task_free(scsi_task_t *task);
404 387 void stmf_do_task_abort(scsi_task_t *task);
405 388 void stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl,
406 389 uint8_t hdlrm_reason);
407 390 void stmf_generate_lu_event(stmf_i_lu_t *ilu, int eventid,
408 391 void *arg, uint32_t flags);
409 392 void stmf_generate_lport_event(stmf_i_local_port_t *ilport, int eventid,
410 393 void *arg, uint32_t flags);
411 394
412 395 #ifdef __cplusplus
413 396 }
414 397 #endif
415 398
416 399 #endif /* _STMF_IMPL_H */
|
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX