ibtl_mem.c revision 43ed929a6988c3778f00123f4a4a8541e515ec16
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/ib/ibtl/impl/ibtl.h>
/*
* ibtl_mem.c
* These routines implement all of the Memory Region verbs and the alloc/
* query/free Memory Window verbs at the TI interface.
*/
static char ibtl_mem[] = "ibtl_mem";
/*
* Function:
* ibt_register_mr()
* Input:
* hca_hdl - HCA Handle.
* pd - Protection Domain Handle.
* mem_attr - Requested memory region attributes.
* Output:
* mr_hdl_p - The returned IBT memory region handle.
* mem_desc - Returned memory descriptor.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MR_VA_INVALID
* IBT_MR_LEN_INVALID
* IBT_MR_ACCESS_REQ_INVALID
* IBT_PD_HDL_INVALID
* IBT_INSUFF_RESOURCE
* Description:
* Prepares a virtually addressed memory region for use by a HCA. A
* description of the registered memory suitable for use in Work Requests
* (WRs) is returned in the ibt_mr_desc_t parameter.
*/
ibt_status_t
ibt_register_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, ibt_mr_attr_t *mem_attr,
ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc)
{
ib_vaddr_t vaddr;
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_mr(%p, %p, %p)",
hca_hdl, pd, mem_attr);
vaddr = mem_attr->mr_vaddr;
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_mr(
IBTL_HCA2CIHCA(hca_hdl), pd, mem_attr, IBTL_HCA2CLNT(hca_hdl),
mr_hdl_p, mem_desc);
if (status == IBT_SUCCESS) {
mem_desc->md_vaddr = vaddr;
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_register_buf()
* Input:
* hca_hdl HCA Handle.
* pd Protection Domain Handle.
* mem_bpattr Memory Registration attributes (IOVA and flags).
* bp A pointer to a buf(9S) struct.
* Output:
* mr_hdl_p The returned IBT memory region handle.
* mem_desc Returned memory descriptor.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MR_VA_INVALID
* IBT_MR_LEN_INVALID
* IBT_MR_ACCESS_REQ_INVALID
* IBT_PD_HDL_INVALID
* IBT_INSUFF_RESOURCE
* Description:
* Prepares a memory region described by a buf(9S) struct for use by a HCA.
* A description of the registered memory suitable for use in
* Work Requests (WRs) is returned in the ibt_mr_desc_t parameter.
*/
ibt_status_t
ibt_register_buf(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
ibt_smr_attr_t *mem_bpattr, struct buf *bp, ibt_mr_hdl_t *mr_hdl_p,
ibt_mr_desc_t *mem_desc)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_buf(%p, %p, %p, %p)",
hca_hdl, pd, mem_bpattr, bp);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_buf(
IBTL_HCA2CIHCA(hca_hdl), pd, mem_bpattr, bp, IBTL_HCA2CLNT(hca_hdl),
mr_hdl_p, mem_desc);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_query_mr()
* Input:
* hca_hdl - HCA Handle.
* mr_hdl - The IBT Memory Region handle.
* Output:
* attr - The pointer to Memory region attributes structure.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MR_HDL_INVALID
* Description:
* Retrieves information about a specified memory region.
*/
ibt_status_t
ibt_query_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
ibt_mr_query_attr_t *attr)
{
IBTF_DPRINTF_L3(ibtl_mem, "ibt_query_mr(%p, %p)", hca_hdl, mr_hdl);
return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_query_mr(
IBTL_HCA2CIHCA(hca_hdl), mr_hdl, attr));
}
/*
* Function:
* ibt_deregister_mr()
* Input:
* hca_hdl - HCA Handle.
* mr_hdl - The IBT Memory Region handle.
* Output:
* none.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MR_HDL_INVALID
* IBT_MR_IN_USE
* Description:
* De-register the registered memory region. Remove a memory region from a
* HCA translation table, and free all resources associated with the
* memory region.
*/
ibt_status_t
ibt_deregister_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_deregister_mr(%p, %p)", hca_hdl, mr_hdl);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_deregister_mr(
IBTL_HCA2CIHCA(hca_hdl), mr_hdl);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_reregister_mr()
* Input:
* hca_hdl - HCA Handle.
* mr_hdl - The IBT Memory Region handle.
* pd - Optional Protection Domain Handle.
* mem_attr - Requested memory region attributes.
* Output:
* mr_hdl_p - The reregistered IBT memory region handle.
* mem_desc - Returned memory descriptor for the new memory region.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MR_HDL_INVALID
* IBT_MR_VA_INVALID
* IBT_MR_LEN_INVALID
* IBT_MR_ACCESS_REQ_INVALID
* IBT_PD_HDL_INVALID
* IBT_INSUFF_RESOURCE
* IBT_MR_IN_USE
* Description:
* Modify the attributes of an existing memory region.
*/
ibt_status_t
ibt_reregister_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl, ibt_pd_hdl_t pd,
ibt_mr_attr_t *mem_attr, ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc)
{
ibt_status_t status;
ib_vaddr_t vaddr = mem_attr->mr_vaddr;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_reregister_mr(%p, %p, %p, %p)",
hca_hdl, mr_hdl, pd, mem_attr);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_reregister_mr(
IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_attr,
IBTL_HCA2CLNT(hca_hdl), mr_hdl_p, mem_desc);
if (status == IBT_SUCCESS)
mem_desc->md_vaddr = vaddr;
else if (!(status == IBT_MR_IN_USE || status == IBT_HCA_HDL_INVALID ||
status == IBT_MR_HDL_INVALID)) {
IBTF_DPRINTF_L2(ibtl_mem, "ibt_reregister_mr: "
"Re-registration Failed: %d", status);
/* we lost one memory region resource */
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_reregister_buf()
* Input:
* hca_hdl HCA Handle.
* mr_hdl The IBT Memory Region handle.
* pd Optional Protection Domain Handle.
* mem_bpattr Memory Registration attributes (IOVA and flags).
* bp A pointer to a buf(9S) struct.
* Output:
* mr_hdl_p The reregistered IBT memory region handle.
* mem_desc Returned memory descriptor for the new memory region.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MR_HDL_INVALID
* IBT_MR_VA_INVALID
* IBT_MR_LEN_INVALID
* IBT_MR_ACCESS_REQ_INVALID
* IBT_PD_HDL_INVALID
* IBT_INSUFF_RESOURCE
* IBT_MR_IN_USE
* Description:
* Modify the attributes of an existing memory region as described by a
* buf(9S) struct for use by a HCA. A description of the registered
* memory suitable for use in Work Requests (WRs) is returned in the
* ibt_mr_desc_t parameter.
*/
ibt_status_t
ibt_reregister_buf(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
ibt_pd_hdl_t pd, ibt_smr_attr_t *mem_bpattr, struct buf *bp,
ibt_mr_hdl_t *mr_hdl_p, ibt_mr_desc_t *mem_desc)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_reregister_buf(%p, %p, %p, %p, %p)",
hca_hdl, mr_hdl, pd, mem_bpattr, bp);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_reregister_buf(
IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_bpattr, bp,
IBTL_HCA2CLNT(hca_hdl), mr_hdl_p, mem_desc);
if (!(status == IBT_SUCCESS || status == IBT_MR_IN_USE ||
status == IBT_HCA_HDL_INVALID || status == IBT_MR_HDL_INVALID)) {
IBTF_DPRINTF_L2(ibtl_mem, "ibt_reregister_buf: "
"Re-registration Mem Failed: %d", status);
/* we lost one memory region resource */
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_register_shared_mr()
* Input:
* hca_hdl - HCA Handle.
* mr_hdl - The IBT Memory Region handle.
* pd - Protection Domain Handle.
* mem_sattr - Requested memory region shared attributes.
* Output:
* mr_hdl_p - The reregistered IBT memory region handle.
* mem_desc - Returned memory descriptor for the new memory region.
* Returns:
* IBT_SUCCESS
* IBT_INSUFF_RESOURCE
* IBT_CHAN_HDL_INVALID
* IBT_MR_HDL_INVALID
* IBT_PD_HDL_INVALID
* IBT_MR_ACCESS_REQ_INVALID
* Description:
* Given an existing memory region, a new memory region associated with
* the same physical locations is created.
*/
ibt_status_t
ibt_register_shared_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
ibt_pd_hdl_t pd, ibt_smr_attr_t *mem_sattr, ibt_mr_hdl_t *mr_hdl_p,
ibt_mr_desc_t *mem_desc)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_shared_mr(%p, %p, %p, %p)",
hca_hdl, mr_hdl, pd, mem_sattr);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_shared_mr(
IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_sattr,
IBTL_HCA2CLNT(hca_hdl), mr_hdl_p, mem_desc);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_sync_mr()
* Input:
* hca_hdl - HCA Handle.
* mr_segments - A pointer to an array of ibt_mr_sync_t that describes
* the memory regions to sync.
* num_segments - The length of the mr_segments array.
* Output:
* NONE
* Returns:
* IBT_SUCCESS
* IBT_HCA_HDL_INVALID
* IBT_MR_HDL_INVALID
* IBT_INVALID_PARAM
* IBT_MR_VA_INVALID
* IBT_MR_LEN_INVALID
* Description:
* Make memory changes visible to incoming RDMA reads, or make the affects
* of an incoming RDMA writes visible to the consumer.
*/
ibt_status_t
ibt_sync_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_sync_t *mr_segments,
size_t num_segments)
{
IBTF_DPRINTF_L3(ibtl_mem, "ibt_sync_mr(%p, %p, %d)", hca_hdl,
mr_segments, num_segments);
return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_sync_mr(
IBTL_HCA2CIHCA(hca_hdl), mr_segments, num_segments));
}
/*
* Function:
* ibt_alloc_mw()
* Input:
* hca_hdl - HCA Handle.
* pd - Protection Domain Handle.
* flags - Memory Window alloc flags.
* Output:
* mw_hdl_p - The returned IBT Memory Window handle.
* rkey - The IBT R_Key handle.
* Returns:
* IBT_SUCCESS
* IBT_INSUFF_RESOURCE
* IBT_CHAN_HDL_INVALID
* IBT_PD_HDL_INVALID
* Description:
* Allocate a memory window from the HCA.
*/
ibt_status_t
ibt_alloc_mw(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, ibt_mw_flags_t flags,
ibt_mw_hdl_t *mw_hdl_p, ibt_rkey_t *rkey)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_alloc_mw(%p, %p, 0x%x)",
hca_hdl, pd, flags);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_mw(
IBTL_HCA2CIHCA(hca_hdl), pd, flags, mw_hdl_p, rkey);
/*
* XXX - We should be able to allocate state and have a IBTF Memory
* Window Handle. Memory Windows are meant to be rebound on the fly
* (using a post) to make them fast. It is expected that alloc memory
* window will be done in a relatively static manner. But, we don't have
* a good reason to have local MW state at this point, so we won't.
*/
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mw_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_query_mw()
* Input:
* hca_hdl - HCA Handle.
* mw_hdl - The IBT Memory Window handle.
* Output:
* pd - Protection Domain Handle.
* rkey - The IBT R_Key handle.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MW_HDL_INVALID
* Description:
* Retrieves information about a specified memory region.
*/
ibt_status_t
ibt_query_mw(ibt_hca_hdl_t hca_hdl, ibt_mw_hdl_t mw_hdl,
ibt_mw_query_attr_t *mw_attr_p)
{
IBTF_DPRINTF_L3(ibtl_mem, "ibt_query_mw(%p, %p)", hca_hdl, mw_hdl);
return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_query_mw(
IBTL_HCA2CIHCA(hca_hdl), mw_hdl, mw_attr_p));
}
/*
* Function:
* ibt_free_mw()
* Input:
* hca_hdl - HCA Handle
* mw_hdl - The IBT Memory Window handle.
* Output:
* none.
* Returns:
* IBT_SUCCESS
* IBT_CHAN_HDL_INVALID
* IBT_MW_HDL_INVALID
* Description:
* De-allocate the Memory Window.
*/
ibt_status_t
ibt_free_mw(ibt_hca_hdl_t hca_hdl, ibt_mw_hdl_t mw_hdl)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_free_mw(%p, %p)", hca_hdl, mw_hdl);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_free_mw(
IBTL_HCA2CIHCA(hca_hdl), mw_hdl);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mw_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_map_mem_area()
* Input:
* hca_hdl HCA Handle
* va_attrs A pointer to an ibt_va_attr_t that describes the
* VA to be translated.
* paddr_list_len The number of entries in the 'paddr_list_p' array.
* Output:
* paddr_list_p Array of ibt_phys_buf_t (allocated by the caller),
* in which the physical buffers that map the virtual
* buffer are returned.
* num_paddr_p The actual number of ibt_phys_buf_t that were
* returned in the 'paddr_list_p' array.
* ma_hdl_p Memory Area Handle.
* Returns:
* IBT_SUCCESS
* Description:
* Translate a kernel virtual address range into HCA physical addresses.
* A set of physical addresses, that can be used with "Reserved L_Key",
* register physical, and "Fast Registration Work Request" operations
* is returned.
*/
ibt_status_t
ibt_map_mem_area(ibt_hca_hdl_t hca_hdl, ibt_va_attr_t *va_attrs,
uint_t paddr_list_len, ibt_phys_buf_t *paddr_list_p, uint_t *num_paddr_p,
size_t *paddr_bufsz_p, ib_memlen_t *paddr_offset_p, ibt_ma_hdl_t *ma_hdl_p)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_map_mem_area(%p, %p, %d)",
hca_hdl, va_attrs, paddr_list_len);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_map_mem_area(
IBTL_HCA2CIHCA(hca_hdl), va_attrs,
NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */
paddr_list_len, paddr_list_p, num_paddr_p, paddr_bufsz_p,
paddr_offset_p, ma_hdl_p);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_ma_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_unmap_mem_area()
* Input:
* hca_hdl HCA Handle
* ma_hdl Memory Area Handle.
* Output:
* None.
* Returns:
* IBT_SUCCESS
* Description:
* Un pin physical pages pinned during an ibt_map_mem_area() call.
*/
ibt_status_t
ibt_unmap_mem_area(ibt_hca_hdl_t hca_hdl, ibt_ma_hdl_t ma_hdl)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_unmap_mem_area(%p, %p)",
hca_hdl, ma_hdl);
status = (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_unmap_mem_area(
IBTL_HCA2CIHCA(hca_hdl), ma_hdl));
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_ma_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_alloc_lkey()
* Input:
* hca_hdl HCA Handle
* pd A protection domain handle.
* flags Access control.
* phys_buf_list_sz Requested size of Physical Buffer List (PBL)
* resources to be allocated.
* Output:
* mr_hdl_p The returned IBT memory region handle.
* mem_desc_p Returned memory descriptor.
* Returns:
* IBT_SUCCESS
* Description:
* Allocates physical buffer list resources for use in memory
* registrations.
*/
ibt_status_t
ibt_alloc_lkey(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd, ibt_lkey_flags_t flags,
uint_t phys_buf_list_sz, ibt_mr_hdl_t *mr_hdl_p,
ibt_pmr_desc_t *mem_desc_p)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_alloc_lkey(%p, %p, 0x%X, %d)",
hca_hdl, pd, flags, phys_buf_list_sz);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_alloc_lkey(
IBTL_HCA2CIHCA(hca_hdl), pd, flags, phys_buf_list_sz, mr_hdl_p,
mem_desc_p);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_register_phys_mr()
* Input:
* hca_hdl HCA Handle
* pd A protection domain handle.
* mem_pattr Requested memory region physical attributes.
* Output:
* mr_hdl_p The returned IBT memory region handle.
* mem_desc_p Returned memory descriptor.
* Returns:
* IBT_SUCCESS
* Description:
* Prepares a physically addressed memory region for use by a HCA.
*/
ibt_status_t
ibt_register_phys_mr(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p,
ibt_pmr_desc_t *mem_desc_p)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_phys_mr(%p, %p, %p)",
hca_hdl, pd, mem_pattr);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_physical_mr(
IBTL_HCA2CIHCA(hca_hdl), pd, mem_pattr,
NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */
mr_hdl_p, mem_desc_p);
if (status == IBT_SUCCESS) {
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Function:
* ibt_reregister_phys_mr()
* Input:
* hca_hdl HCA Handle
* mr_hdl The IBT memory region handle.
* pd A protection domain handle.
* mem_pattr Requested memory region physical attributes.
* Output:
* mr_hdl_p The returned IBT memory region handle.
* mem_desc_p Returned memory descriptor.
* Returns:
* IBT_SUCCESS
* Description:
* Prepares a physically addressed memory region for use by a HCA.
*/
ibt_status_t
ibt_reregister_phys_mr(ibt_hca_hdl_t hca_hdl, ibt_mr_hdl_t mr_hdl,
ibt_pd_hdl_t pd, ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p,
ibt_pmr_desc_t *mem_desc_p)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_reregister_phys_mr(%p, %p, %p, %p)",
hca_hdl, mr_hdl, pd, mem_pattr);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_reregister_physical_mr(
IBTL_HCA2CIHCA(hca_hdl), mr_hdl, pd, mem_pattr,
NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */
mr_hdl_p, mem_desc_p);
if (!(status == IBT_SUCCESS || status == IBT_MR_IN_USE ||
status == IBT_HCA_HDL_INVALID || status == IBT_MR_HDL_INVALID)) {
IBTF_DPRINTF_L2(ibtl_mem, "ibt_reregister_phys_mr: "
"Re-registration Mem Failed: %d", status);
/* we lost one memory region resource */
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_mr_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
}
return (status);
}
/*
* Fast Memory Registration (FMR).
*
* ibt_create_fmr_pool
* Not fast-path.
* ibt_create_fmr_pool() verifies that the HCA supports FMR and allocates
* and initializes an "FMR pool". This pool contains state specific to
* this registration, including the watermark setting to determine when
* to sync, and the total number of FMR regions available within this pool.
*
*/
ibt_status_t
ibt_create_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_pd_hdl_t pd,
ibt_fmr_pool_attr_t *fmr_params, ibt_fmr_pool_hdl_t *fmr_pool_p)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_create_fmr_pool(%p, %p, %p)",
hca_hdl, pd, fmr_params);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_create_fmr_pool(
IBTL_HCA2CIHCA(hca_hdl), pd, fmr_params, fmr_pool_p);
if (status != IBT_SUCCESS) {
*fmr_pool_p = NULL;
return (status);
}
/* Update the FMR resource count */
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_fmr_pool_cnt++;
mutex_exit(&hca_hdl->ha_mutex);
return (status);
}
/*
* ibt_destroy_fmr_pool
* ibt_destroy_fmr_pool() deallocates all of the FMR regions in a specific
* pool. All state and information regarding the pool are destroyed and
* returned as free space once again. No more use of FMR regions in this
* pool are possible without a subsequent call to ibt_create_fmr_pool().
*/
ibt_status_t
ibt_destroy_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_fmr_pool_hdl_t fmr_pool)
{
ibt_status_t status;
IBTF_DPRINTF_L3(ibtl_mem, "ibt_destroy_fmr_pool(%p, %p)",
hca_hdl, fmr_pool);
status = IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_destroy_fmr_pool(
IBTL_HCA2CIHCA(hca_hdl), fmr_pool);
if (status != IBT_SUCCESS) {
IBTF_DPRINTF_L2(ibtl_mem, "ibt_destroy_fmr_pool: "
"CI FMR Pool destroy failed (%d)", status);
return (status);
}
mutex_enter(&hca_hdl->ha_mutex);
hca_hdl->ha_fmr_pool_cnt--;
mutex_exit(&hca_hdl->ha_mutex);
return (status);
}
/*
* ibt_flush_fmr_pool
* ibt_flush_fmr_pool forces a flush to occur. At the client's request,
* any unmapped FMR regions (See 'ibt_deregister_mr())') are returned to
* a free state. This function allows for an asynchronous cleanup of
* formerly used FMR regions. Sync operation is also performed internally
* by HCA driver, when 'watermark' settings for the number of free FMR
* regions left in the "pool" is reached.
*/
ibt_status_t
ibt_flush_fmr_pool(ibt_hca_hdl_t hca_hdl, ibt_fmr_pool_hdl_t fmr_pool)
{
IBTF_DPRINTF_L3(ibtl_mem, "ibt_flush_fmr_pool(%p, %p)",
hca_hdl, fmr_pool);
return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_flush_fmr_pool(
IBTL_HCA2CIHCA(hca_hdl), fmr_pool));
}
/*
* ibt_register_physical_fmr
* ibt_register_physical_fmr() assigns a "free" entry from the FMR Pool.
* It first consults the "FMR cache" to see if this is a duplicate memory
* registration to something already in use. If not, then a free entry
* in the "pool" is marked used.
*/
ibt_status_t
ibt_register_physical_fmr(ibt_hca_hdl_t hca_hdl, ibt_fmr_pool_hdl_t fmr_pool,
ibt_pmr_attr_t *mem_pattr, ibt_mr_hdl_t *mr_hdl_p,
ibt_pmr_desc_t *mem_desc_p)
{
IBTF_DPRINTF_L3(ibtl_mem, "ibt_register_physical_fmr(%p, %p, %p, %p)",
hca_hdl, fmr_pool, mem_pattr, mem_desc_p);
return (IBTL_HCA2CIHCAOPS_P(hca_hdl)->ibc_register_physical_fmr(
IBTL_HCA2CIHCA(hca_hdl), fmr_pool, mem_pattr,
NULL, /* IBTL_HCA2MODI_P(hca_hdl)->mi_reserved */
mr_hdl_p, mem_desc_p));
}
/*
* ibt_deregister_fmr
* The ibt_deregister_fmr un-maps the resources reserved from the FMR
* pool by ibt_register_physical_fmr(). The ibt_deregister_fmr() will
* mark the region as free in the FMR Pool.
*/
ibt_status_t
ibt_deregister_fmr(ibt_hca_hdl_t hca, ibt_mr_hdl_t mr_hdl)
{
IBTF_DPRINTF_L3(ibtl_mem, "ibt_deregister_fmr(%p, %p)", hca, mr_hdl);
return (IBTL_HCA2CIHCAOPS_P(hca)->ibc_deregister_fmr(
IBTL_HCA2CIHCA(hca), mr_hdl));
}