.. | .. |
---|
65 | 65 | #include <linux/in6.h> |
---|
66 | 66 | |
---|
67 | 67 | #include <rdma/ib_verbs.h> |
---|
68 | | -#include <rdma/ib_fmr_pool.h> |
---|
69 | 68 | #include <rdma/rdma_cm.h> |
---|
70 | 69 | |
---|
71 | 70 | #define DRV_NAME "iser" |
---|
.. | .. |
---|
96 | 95 | #define iser_err(fmt, arg...) \ |
---|
97 | 96 | pr_err(PFX "%s: " fmt, __func__ , ## arg) |
---|
98 | 97 | |
---|
99 | | -#define SHIFT_4K 12 |
---|
100 | | -#define SIZE_4K (1ULL << SHIFT_4K) |
---|
101 | | -#define MASK_4K (~(SIZE_4K-1)) |
---|
102 | | - |
---|
103 | 98 | /* Default support is 512KB I/O size */ |
---|
104 | 99 | #define ISER_DEF_MAX_SECTORS 1024 |
---|
105 | | -#define ISCSI_ISER_DEF_SG_TABLESIZE ((ISER_DEF_MAX_SECTORS * 512) >> SHIFT_4K) |
---|
106 | | -/* Maximum support is 8MB I/O size */ |
---|
107 | | -#define ISCSI_ISER_MAX_SG_TABLESIZE ((16384 * 512) >> SHIFT_4K) |
---|
| 100 | +#define ISCSI_ISER_DEF_SG_TABLESIZE \ |
---|
| 101 | + ((ISER_DEF_MAX_SECTORS * SECTOR_SIZE) >> ilog2(SZ_4K)) |
---|
| 102 | +/* Maximum support is 16MB I/O size */ |
---|
| 103 | +#define ISCSI_ISER_MAX_SG_TABLESIZE ((32768 * SECTOR_SIZE) >> ilog2(SZ_4K)) |
---|
108 | 104 | |
---|
109 | 105 | #define ISER_DEF_XMIT_CMDS_DEFAULT 512 |
---|
110 | 106 | #if ISCSI_DEF_XMIT_CMDS_MAX > ISER_DEF_XMIT_CMDS_DEFAULT |
---|
.. | .. |
---|
225 | 221 | ISCSI_TX_DATAOUT |
---|
226 | 222 | }; |
---|
227 | 223 | |
---|
228 | | -/* Maximum number of work requests per task: |
---|
229 | | - * Data memory region local invalidate + fast registration |
---|
230 | | - * Protection memory region local invalidate + fast registration |
---|
231 | | - * Signature memory region local invalidate + fast registration |
---|
232 | | - * PDU send |
---|
233 | | - */ |
---|
234 | | -#define ISER_MAX_WRS 7 |
---|
235 | | - |
---|
236 | 224 | /** |
---|
237 | 225 | * struct iser_tx_desc - iSER TX descriptor |
---|
238 | 226 | * |
---|
239 | 227 | * @iser_header: iser header |
---|
240 | 228 | * @iscsi_header: iscsi header |
---|
241 | 229 | * @type: command/control/dataout |
---|
242 | | - * @dam_addr: header buffer dma_address |
---|
| 230 | + * @dma_addr: header buffer dma_address |
---|
243 | 231 | * @tx_sg: sg[0] points to iser/iscsi headers |
---|
244 | 232 | * sg[1] optionally points to either of immediate data |
---|
245 | 233 | * unsolicited data-out or control |
---|
246 | 234 | * @num_sge: number sges used on this TX task |
---|
| 235 | + * @cqe: completion handler |
---|
247 | 236 | * @mapped: Is the task header mapped |
---|
248 | | - * @wr_idx: Current WR index |
---|
249 | | - * @wrs: Array of WRs per task |
---|
250 | | - * @data_reg: Data buffer registration details |
---|
251 | | - * @prot_reg: Protection buffer registration details |
---|
252 | | - * @sig_attrs: Signature attributes |
---|
| 237 | + * @reg_wr: registration WR |
---|
| 238 | + * @send_wr: send WR |
---|
| 239 | + * @inv_wr: invalidate WR |
---|
253 | 240 | */ |
---|
254 | 241 | struct iser_tx_desc { |
---|
255 | 242 | struct iser_ctrl iser_header; |
---|
.. | .. |
---|
260 | 247 | int num_sge; |
---|
261 | 248 | struct ib_cqe cqe; |
---|
262 | 249 | bool mapped; |
---|
263 | | - u8 wr_idx; |
---|
264 | | - union iser_wr { |
---|
265 | | - struct ib_send_wr send; |
---|
266 | | - struct ib_reg_wr fast_reg; |
---|
267 | | - struct ib_sig_handover_wr sig; |
---|
268 | | - } wrs[ISER_MAX_WRS]; |
---|
269 | | - struct iser_mem_reg data_reg; |
---|
270 | | - struct iser_mem_reg prot_reg; |
---|
271 | | - struct ib_sig_attrs sig_attrs; |
---|
| 250 | + struct ib_reg_wr reg_wr; |
---|
| 251 | + struct ib_send_wr send_wr; |
---|
| 252 | + struct ib_send_wr inv_wr; |
---|
272 | 253 | }; |
---|
273 | 254 | |
---|
274 | 255 | #define ISER_RX_PAD_SIZE (256 - (ISER_RX_PAYLOAD_SIZE + \ |
---|
.. | .. |
---|
282 | 263 | * @data: received data segment |
---|
283 | 264 | * @dma_addr: receive buffer dma address |
---|
284 | 265 | * @rx_sg: ib_sge of receive buffer |
---|
| 266 | + * @cqe: completion handler |
---|
285 | 267 | * @pad: for sense data TODO: Modify to maximum sense length supported |
---|
286 | 268 | */ |
---|
287 | 269 | struct iser_rx_desc { |
---|
.. | .. |
---|
298 | 280 | * struct iser_login_desc - iSER login descriptor |
---|
299 | 281 | * |
---|
300 | 282 | * @req: pointer to login request buffer |
---|
301 | | - * @resp: pointer to login response buffer |
---|
| 283 | + * @rsp: pointer to login response buffer |
---|
302 | 284 | * @req_dma: DMA address of login request buffer |
---|
303 | | - * @rsp_dma: DMA address of login response buffer |
---|
| 285 | + * @rsp_dma: DMA address of login response buffer |
---|
304 | 286 | * @sge: IB sge for login post recv |
---|
305 | 287 | * @cqe: completion handler |
---|
306 | 288 | */ |
---|
.. | .. |
---|
311 | 293 | u64 rsp_dma; |
---|
312 | 294 | struct ib_sge sge; |
---|
313 | 295 | struct ib_cqe cqe; |
---|
314 | | -} __attribute__((packed)); |
---|
| 296 | +} __packed; |
---|
315 | 297 | |
---|
316 | 298 | struct iser_conn; |
---|
317 | 299 | struct ib_conn; |
---|
318 | 300 | struct iscsi_iser_task; |
---|
319 | | - |
---|
320 | | -/** |
---|
321 | | - * struct iser_comp - iSER completion context |
---|
322 | | - * |
---|
323 | | - * @cq: completion queue |
---|
324 | | - * @active_qps: Number of active QPs attached |
---|
325 | | - * to completion context |
---|
326 | | - */ |
---|
327 | | -struct iser_comp { |
---|
328 | | - struct ib_cq *cq; |
---|
329 | | - int active_qps; |
---|
330 | | -}; |
---|
331 | | - |
---|
332 | | -/** |
---|
333 | | - * struct iser_device - Memory registration operations |
---|
334 | | - * per-device registration schemes |
---|
335 | | - * |
---|
336 | | - * @alloc_reg_res: Allocate registration resources |
---|
337 | | - * @free_reg_res: Free registration resources |
---|
338 | | - * @fast_reg_mem: Register memory buffers |
---|
339 | | - * @unreg_mem: Un-register memory buffers |
---|
340 | | - * @reg_desc_get: Get a registration descriptor for pool |
---|
341 | | - * @reg_desc_put: Get a registration descriptor to pool |
---|
342 | | - */ |
---|
343 | | -struct iser_reg_ops { |
---|
344 | | - int (*alloc_reg_res)(struct ib_conn *ib_conn, |
---|
345 | | - unsigned cmds_max, |
---|
346 | | - unsigned int size); |
---|
347 | | - void (*free_reg_res)(struct ib_conn *ib_conn); |
---|
348 | | - int (*reg_mem)(struct iscsi_iser_task *iser_task, |
---|
349 | | - struct iser_data_buf *mem, |
---|
350 | | - struct iser_reg_resources *rsc, |
---|
351 | | - struct iser_mem_reg *reg); |
---|
352 | | - void (*unreg_mem)(struct iscsi_iser_task *iser_task, |
---|
353 | | - enum iser_data_dir cmd_dir); |
---|
354 | | - struct iser_fr_desc * (*reg_desc_get)(struct ib_conn *ib_conn); |
---|
355 | | - void (*reg_desc_put)(struct ib_conn *ib_conn, |
---|
356 | | - struct iser_fr_desc *desc); |
---|
357 | | -}; |
---|
358 | 301 | |
---|
359 | 302 | /** |
---|
360 | 303 | * struct iser_device - iSER device handle |
---|
.. | .. |
---|
365 | 308 | * @event_handler: IB events handle routine |
---|
366 | 309 | * @ig_list: entry in devices list |
---|
367 | 310 | * @refcount: Reference counter, dominated by open iser connections |
---|
368 | | - * @comps_used: Number of completion contexts used, Min between online |
---|
369 | | - * cpus and device max completion vectors |
---|
370 | | - * @comps: Dinamically allocated array of completion handlers |
---|
371 | | - * @reg_ops: Registration ops |
---|
372 | | - * @remote_inv_sup: Remote invalidate is supported on this device |
---|
373 | 311 | */ |
---|
374 | 312 | struct iser_device { |
---|
375 | 313 | struct ib_device *ib_device; |
---|
.. | .. |
---|
377 | 315 | struct ib_event_handler event_handler; |
---|
378 | 316 | struct list_head ig_list; |
---|
379 | 317 | int refcount; |
---|
380 | | - int comps_used; |
---|
381 | | - struct iser_comp *comps; |
---|
382 | | - const struct iser_reg_ops *reg_ops; |
---|
383 | | - bool remote_inv_sup; |
---|
384 | 318 | }; |
---|
385 | 319 | |
---|
386 | 320 | /** |
---|
387 | | - * struct iser_reg_resources - Fast registration recources |
---|
| 321 | + * struct iser_reg_resources - Fast registration resources |
---|
388 | 322 | * |
---|
389 | 323 | * @mr: memory region |
---|
390 | | - * @fmr_pool: pool of fmrs |
---|
391 | | - * @page_vec: fast reg page list used by fmr pool |
---|
| 324 | + * @sig_mr: signature memory region |
---|
392 | 325 | * @mr_valid: is mr valid indicator |
---|
393 | 326 | */ |
---|
394 | 327 | struct iser_reg_resources { |
---|
395 | | - union { |
---|
396 | | - struct ib_mr *mr; |
---|
397 | | - struct ib_fmr_pool *fmr_pool; |
---|
398 | | - }; |
---|
399 | | - struct iser_page_vec *page_vec; |
---|
| 328 | + struct ib_mr *mr; |
---|
| 329 | + struct ib_mr *sig_mr; |
---|
400 | 330 | u8 mr_valid:1; |
---|
401 | | -}; |
---|
402 | | - |
---|
403 | | -/** |
---|
404 | | - * struct iser_pi_context - Protection information context |
---|
405 | | - * |
---|
406 | | - * @rsc: protection buffer registration resources |
---|
407 | | - * @sig_mr: signature enable memory region |
---|
408 | | - * @sig_mr_valid: is sig_mr valid indicator |
---|
409 | | - * @sig_protected: is region protected indicator |
---|
410 | | - */ |
---|
411 | | -struct iser_pi_context { |
---|
412 | | - struct iser_reg_resources rsc; |
---|
413 | | - struct ib_mr *sig_mr; |
---|
414 | | - u8 sig_mr_valid:1; |
---|
415 | | - u8 sig_protected:1; |
---|
416 | 331 | }; |
---|
417 | 332 | |
---|
418 | 333 | /** |
---|
.. | .. |
---|
420 | 335 | * |
---|
421 | 336 | * @list: entry in connection fastreg pool |
---|
422 | 337 | * @rsc: data buffer registration resources |
---|
423 | | - * @pi_ctx: protection information context |
---|
| 338 | + * @sig_protected: is region protected indicator |
---|
| 339 | + * @all_list: first and last list members |
---|
424 | 340 | */ |
---|
425 | 341 | struct iser_fr_desc { |
---|
426 | 342 | struct list_head list; |
---|
427 | 343 | struct iser_reg_resources rsc; |
---|
428 | | - struct iser_pi_context *pi_ctx; |
---|
| 344 | + bool sig_protected; |
---|
429 | 345 | struct list_head all_list; |
---|
430 | 346 | }; |
---|
431 | 347 | |
---|
432 | 348 | /** |
---|
433 | | - * struct iser_fr_pool: connection fast registration pool |
---|
| 349 | + * struct iser_fr_pool - connection fast registration pool |
---|
434 | 350 | * |
---|
435 | 351 | * @list: list of fastreg descriptors |
---|
436 | | - * @lock: protects fmr/fastreg pool |
---|
| 352 | + * @lock: protects fastreg pool |
---|
437 | 353 | * @size: size of the pool |
---|
| 354 | + * @all_list: first and last list members |
---|
438 | 355 | */ |
---|
439 | 356 | struct iser_fr_pool { |
---|
440 | 357 | struct list_head list; |
---|
.. | .. |
---|
448 | 365 | * |
---|
449 | 366 | * @cma_id: rdma_cm connection maneger handle |
---|
450 | 367 | * @qp: Connection Queue-pair |
---|
| 368 | + * @cq: Connection completion queue |
---|
| 369 | + * @cq_size: The number of max outstanding completions |
---|
451 | 370 | * @post_recv_buf_count: post receive counter |
---|
452 | 371 | * @sig_count: send work request signal count |
---|
453 | 372 | * @rx_wr: receive work request for batch posts |
---|
454 | 373 | * @device: reference to iser device |
---|
455 | | - * @comp: iser completion context |
---|
456 | 374 | * @fr_pool: connection fast registration poool |
---|
457 | 375 | * @pi_support: Indicate device T10-PI support |
---|
| 376 | + * @reg_cqe: completion handler |
---|
458 | 377 | */ |
---|
459 | 378 | struct ib_conn { |
---|
460 | 379 | struct rdma_cm_id *cma_id; |
---|
461 | 380 | struct ib_qp *qp; |
---|
| 381 | + struct ib_cq *cq; |
---|
| 382 | + u32 cq_size; |
---|
462 | 383 | int post_recv_buf_count; |
---|
463 | 384 | u8 sig_count; |
---|
464 | 385 | struct ib_recv_wr rx_wr[ISER_MIN_POSTED_RX]; |
---|
465 | 386 | struct iser_device *device; |
---|
466 | | - struct iser_comp *comp; |
---|
467 | 387 | struct iser_fr_pool fr_pool; |
---|
468 | 388 | bool pi_support; |
---|
469 | 389 | struct ib_cqe reg_cqe; |
---|
.. | .. |
---|
495 | 415 | * @num_rx_descs: number of rx descriptors |
---|
496 | 416 | * @scsi_sg_tablesize: scsi host sg_tablesize |
---|
497 | 417 | * @pages_per_mr: maximum pages available for registration |
---|
| 418 | + * @snd_w_inv: connection uses remote invalidation |
---|
498 | 419 | */ |
---|
499 | 420 | struct iser_conn { |
---|
500 | 421 | struct ib_conn ib_conn; |
---|
.. | .. |
---|
546 | 467 | struct iser_data_buf prot[ISER_DIRS_NUM]; |
---|
547 | 468 | }; |
---|
548 | 469 | |
---|
549 | | -struct iser_page_vec { |
---|
550 | | - u64 *pages; |
---|
551 | | - int npages; |
---|
552 | | - struct ib_mr fake_mr; |
---|
553 | | -}; |
---|
554 | | - |
---|
555 | 470 | /** |
---|
556 | | - * struct iser_global: iSER global context |
---|
| 471 | + * struct iser_global - iSER global context |
---|
557 | 472 | * |
---|
558 | 473 | * @device_list_mutex: protects device_list |
---|
559 | 474 | * @device_list: iser devices global list |
---|
.. | .. |
---|
575 | 490 | extern int iser_pi_guard; |
---|
576 | 491 | extern unsigned int iser_max_sectors; |
---|
577 | 492 | extern bool iser_always_reg; |
---|
578 | | - |
---|
579 | | -int iser_assign_reg_ops(struct iser_device *device); |
---|
580 | 493 | |
---|
581 | 494 | int iser_send_control(struct iscsi_conn *conn, |
---|
582 | 495 | struct iscsi_task *task); |
---|
.. | .. |
---|
619 | 532 | struct iser_data_buf *mem, |
---|
620 | 533 | enum iser_data_dir cmd_dir); |
---|
621 | 534 | |
---|
622 | | -int iser_reg_rdma_mem(struct iscsi_iser_task *task, |
---|
623 | | - enum iser_data_dir dir, |
---|
624 | | - bool all_imm); |
---|
625 | | -void iser_unreg_rdma_mem(struct iscsi_iser_task *task, |
---|
626 | | - enum iser_data_dir dir); |
---|
| 535 | +int iser_reg_mem_fastreg(struct iscsi_iser_task *task, |
---|
| 536 | + enum iser_data_dir dir, |
---|
| 537 | + bool all_imm); |
---|
| 538 | +void iser_unreg_mem_fastreg(struct iscsi_iser_task *task, |
---|
| 539 | + enum iser_data_dir dir); |
---|
627 | 540 | |
---|
628 | 541 | int iser_connect(struct iser_conn *iser_conn, |
---|
629 | 542 | struct sockaddr *src_addr, |
---|
630 | 543 | struct sockaddr *dst_addr, |
---|
631 | 544 | int non_blocking); |
---|
632 | | - |
---|
633 | | -void iser_unreg_mem_fmr(struct iscsi_iser_task *iser_task, |
---|
634 | | - enum iser_data_dir cmd_dir); |
---|
635 | | -void iser_unreg_mem_fastreg(struct iscsi_iser_task *iser_task, |
---|
636 | | - enum iser_data_dir cmd_dir); |
---|
637 | 545 | |
---|
638 | 546 | int iser_post_recvl(struct iser_conn *iser_conn); |
---|
639 | 547 | int iser_post_recvm(struct iser_conn *iser_conn, int count); |
---|
.. | .. |
---|
653 | 561 | struct iser_tx_desc *tx_desc); |
---|
654 | 562 | int iser_alloc_rx_descriptors(struct iser_conn *iser_conn, |
---|
655 | 563 | struct iscsi_session *session); |
---|
656 | | -int iser_alloc_fmr_pool(struct ib_conn *ib_conn, |
---|
657 | | - unsigned cmds_max, |
---|
658 | | - unsigned int size); |
---|
659 | | -void iser_free_fmr_pool(struct ib_conn *ib_conn); |
---|
660 | 564 | int iser_alloc_fastreg_pool(struct ib_conn *ib_conn, |
---|
661 | 565 | unsigned cmds_max, |
---|
662 | 566 | unsigned int size); |
---|
663 | 567 | void iser_free_fastreg_pool(struct ib_conn *ib_conn); |
---|
664 | 568 | u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, |
---|
665 | 569 | enum iser_data_dir cmd_dir, sector_t *sector); |
---|
666 | | -struct iser_fr_desc * |
---|
667 | | -iser_reg_desc_get_fr(struct ib_conn *ib_conn); |
---|
668 | | -void |
---|
669 | | -iser_reg_desc_put_fr(struct ib_conn *ib_conn, |
---|
670 | | - struct iser_fr_desc *desc); |
---|
671 | | -struct iser_fr_desc * |
---|
672 | | -iser_reg_desc_get_fmr(struct ib_conn *ib_conn); |
---|
673 | | -void |
---|
674 | | -iser_reg_desc_put_fmr(struct ib_conn *ib_conn, |
---|
675 | | - struct iser_fr_desc *desc); |
---|
676 | | - |
---|
677 | | -static inline struct ib_send_wr * |
---|
678 | | -iser_tx_next_wr(struct iser_tx_desc *tx_desc) |
---|
679 | | -{ |
---|
680 | | - struct ib_send_wr *cur_wr = &tx_desc->wrs[tx_desc->wr_idx].send; |
---|
681 | | - struct ib_send_wr *last_wr; |
---|
682 | | - |
---|
683 | | - if (tx_desc->wr_idx) { |
---|
684 | | - last_wr = &tx_desc->wrs[tx_desc->wr_idx - 1].send; |
---|
685 | | - last_wr->next = cur_wr; |
---|
686 | | - } |
---|
687 | | - tx_desc->wr_idx++; |
---|
688 | | - |
---|
689 | | - return cur_wr; |
---|
690 | | -} |
---|
691 | 570 | |
---|
692 | 571 | static inline struct iser_conn * |
---|
693 | 572 | to_iser_conn(struct ib_conn *ib_conn) |
---|