Commit 5cfb1782 authored by Bart Van Assche's avatar Bart Van Assche Committed by Roland Dreier

IB/srp: Add fast registration support

Certain HCA types (e.g. Connect-IB) and certain configurations (e.g.
ConnectX VF) support fast registration but not FMR. Hence add fast
registration support.

In function srp_rport_reconnect(), move the the srp_finish_req()
loop from after to before the srp_create_target_ib() call. This is
needed to avoid that srp_finish_req() tries to queue any
invalidation requests for rkeys associated with the old queue pair
on the newly allocated queue pair. Invoking srp_finish_req() before
the queue pair has been reallocated is safe since srp_claim_req()
handles completions correctly that arrive after srp_finish_req()
has been invoked.
Signed-off-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent 52ede08f
This diff is collapsed.
...@@ -68,8 +68,8 @@ enum { ...@@ -68,8 +68,8 @@ enum {
SRP_MAX_PAGES_PER_MR = 512, SRP_MAX_PAGES_PER_MR = 512,
SRP_MAP_ALLOW_FMR = 0, LOCAL_INV_WR_ID_MASK = 1,
SRP_MAP_NO_FMR = 1, FAST_REG_WR_ID_MASK = 2,
}; };
enum srp_target_state { enum srp_target_state {
...@@ -83,6 +83,12 @@ enum srp_iu_type { ...@@ -83,6 +83,12 @@ enum srp_iu_type {
SRP_IU_RSP, SRP_IU_RSP,
}; };
/*
* @mr_page_mask: HCA memory registration page mask.
* @mr_page_size: HCA memory registration page size.
* @mr_max_size: Maximum size in bytes of a single FMR / FR registration
* request.
*/
struct srp_device { struct srp_device {
struct list_head dev_list; struct list_head dev_list;
struct ib_device *dev; struct ib_device *dev;
...@@ -93,6 +99,8 @@ struct srp_device { ...@@ -93,6 +99,8 @@ struct srp_device {
int mr_max_size; int mr_max_size;
int max_pages_per_mr; int max_pages_per_mr;
bool has_fmr; bool has_fmr;
bool has_fr;
bool use_fast_reg;
}; };
struct srp_host { struct srp_host {
...@@ -110,7 +118,10 @@ struct srp_request { ...@@ -110,7 +118,10 @@ struct srp_request {
struct list_head list; struct list_head list;
struct scsi_cmnd *scmnd; struct scsi_cmnd *scmnd;
struct srp_iu *cmd; struct srp_iu *cmd;
struct ib_pool_fmr **fmr_list; union {
struct ib_pool_fmr **fmr_list;
struct srp_fr_desc **fr_list;
};
u64 *map_page; u64 *map_page;
struct srp_direct_buf *indirect_desc; struct srp_direct_buf *indirect_desc;
dma_addr_t indirect_dma_addr; dma_addr_t indirect_dma_addr;
...@@ -129,7 +140,10 @@ struct srp_target_port { ...@@ -129,7 +140,10 @@ struct srp_target_port {
struct ib_cq *send_cq ____cacheline_aligned_in_smp; struct ib_cq *send_cq ____cacheline_aligned_in_smp;
struct ib_cq *recv_cq; struct ib_cq *recv_cq;
struct ib_qp *qp; struct ib_qp *qp;
struct ib_fmr_pool *fmr_pool; union {
struct ib_fmr_pool *fmr_pool;
struct srp_fr_pool *fr_pool;
};
u32 lkey; u32 lkey;
u32 rkey; u32 rkey;
enum srp_target_state state; enum srp_target_state state;
...@@ -196,8 +210,59 @@ struct srp_iu { ...@@ -196,8 +210,59 @@ struct srp_iu {
enum dma_data_direction direction; enum dma_data_direction direction;
}; };
/**
* struct srp_fr_desc - fast registration work request arguments
* @entry: Entry in srp_fr_pool.free_list.
* @mr: Memory region.
* @frpl: Fast registration page list.
*/
struct srp_fr_desc {
struct list_head entry;
struct ib_mr *mr;
struct ib_fast_reg_page_list *frpl;
};
/**
* struct srp_fr_pool - pool of fast registration descriptors
*
* An entry is available for allocation if and only if it occurs in @free_list.
*
* @size: Number of descriptors in this pool.
* @max_page_list_len: Maximum fast registration work request page list length.
* @lock: Protects free_list.
* @free_list: List of free descriptors.
* @desc: Fast registration descriptor pool.
*/
struct srp_fr_pool {
int size;
int max_page_list_len;
spinlock_t lock;
struct list_head free_list;
struct srp_fr_desc desc[0];
};
/**
* struct srp_map_state - per-request DMA memory mapping state
* @desc: Pointer to the element of the SRP buffer descriptor array
* that is being filled in.
* @pages: Array with DMA addresses of pages being considered for
* memory registration.
* @base_dma_addr: DMA address of the first page that has not yet been mapped.
* @dma_len: Number of bytes that will be registered with the next
* FMR or FR memory registration call.
* @total_len: Total number of bytes in the sg-list being mapped.
* @npages: Number of page addresses in the pages[] array.
* @nmdesc: Number of FMR or FR memory descriptors used for mapping.
* @ndesc: Number of SRP buffer descriptors that have been filled in.
* @unmapped_sg: First element of the sg-list that is mapped via FMR or FR.
* @unmapped_index: Index of the first element mapped via FMR or FR.
* @unmapped_addr: DMA address of the first element mapped via FMR or FR.
*/
struct srp_map_state { struct srp_map_state {
struct ib_pool_fmr **next_fmr; union {
struct ib_pool_fmr **next_fmr;
struct srp_fr_desc **next_fr;
};
struct srp_direct_buf *desc; struct srp_direct_buf *desc;
u64 *pages; u64 *pages;
dma_addr_t base_dma_addr; dma_addr_t base_dma_addr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment