2026-01-29 22:25:33 +08:00

229 lines
10 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2021 - 2023, Shanghai Yunsilicon Technology Co., Ltd.
* All rights reserved.
*/
#if !defined(PEER_MEM_H)
#define PEER_MEM_H
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/scatterlist.h>
#define IB_PEER_MEMORY_NAME_MAX 64
#define IB_PEER_MEMORY_VER_MAX 16
#define PEER_MEM_U64_CORE_CONTEXT
/**
* struct peer_memory_client - registration information for peer client.
* @name: peer client name
* @version: peer client version
* @acquire: callback function to be used by IB core to detect whether a
* virtual address in under the responsibility of a specific peer client.
* @get_pages: callback function to be used by IB core asking the peer client to pin
* the physical pages of the given address range and returns that information.
* It equivalents to the kernel API of get_user_pages(), but targets peer memory.
* @dma_map: callback function to be used by IB core asking the peer client to fill
* the dma address mapping for a given address range.
* @dma_unmap: callback function to be used by IB core asking the peer client to take
* relevant actions to unmap the memory.
* @put_pages: callback function to be used by IB core asking the peer client to remove the
* pinning from the given memory.
* It's the peer-direct equivalent of the kernel API put_page.
* @get_page_size: callback function to be used by IB core to query the peer client for
* the page size for the given allocation.
* @release: callback function to be used by IB core asking peer client to release all
* resources associated with previous acquire call. The call will be performed
* only for contexts that have been successfully acquired (i.e. acquire returned a
* non-zero value).
* Additionally, IB core guarentees that there will be no pages pinned through this
* context when the callback is called.
*
* The subsections in this description contain detailed description
* of the callback arguments and expected return values for the
* callbacks defined in this struct.
*
* acquire:
*
* Callback function to be used by IB core to detect
* whether a virtual address in under the responsibility
* of a specific peer client.
*
* addr [IN] - virtual address to be checked whether belongs to peer.
*
* size [IN] - size of memory area starting at addr.
*
* peer_mem_private_data [IN] - The contents of ib_ucontext-> peer_mem_private_data.
* This parameter allows usage of the peer-direct
* API in implementations where it is impossible
* to detect if the memory belongs to the device
* based upon the virtual address alone. In such
* cases, the peer device can create a special
* ib_ucontext, which will be associated with the
* relevant peer memory.
*
* peer_mem_name [IN] - The contents of ib_ucontext-> peer_mem_name.
* Used to identify the peer memory client that
* initialized the ib_ucontext.
* This parameter is normally used along with
* peer_mem_private_data.
* client_context [OUT] - peer opaque data which holds a peer context for
* the acquired address range, will be provided
* back to the peer memory in subsequent
* calls for that given memory.
*
* If peer takes responsibility on the given address range further calls for memory
* management will be directed to the callbacks of this peer client.
*
* Return - 1 in case peer client takes responsibility on that range otherwise 0.
* Any peer internal error should resulted in a zero answer, in case address
* range really belongs to the peer, no owner will be found and application
* will get an error
* from IB Core as expected.
*
* get_pages:
*
* Callback function to be used by IB core asking the
* peer client to pin the physical pages of the given
* address range and returns that information. It
* equivalents to the kernel API of get_user_pages(), but
* targets peer memory.
*
* addr [IN] - start virtual address of that given allocation.
*
* size [IN] - size of memory area starting at addr.
*
* write [IN] - indicates whether the pages will be written to by the caller.
* Same meaning as of kernel API get_user_pages, can be
* ignored if not relevant.
*
* force [IN] - indicates whether to force write access even if user
* mapping is read only. Same meaning as of kernel API
* get_user_pages, can be ignored if not relevant.
*
* sg_head [IN/OUT] - pointer to head of struct sg_table.
* The peer client should allocate a table big
* enough to store all of the required entries. This
* function should fill the table with physical addresses
* and sizes of the memory segments composing this
* memory mapping.
* The table allocation can be done using sg_alloc_table.
* Filling in the physical memory addresses and size can
* be done using sg_set_page.
*
* client_context [IN] - peer context for the given allocation, as received from
* the acquire call.
*
* core_context [IN] - IB core context. If the peer client wishes to
* invalidate any of the pages pinned through this API,
* it must provide this context as an argument to the
* invalidate callback.
*
* Return - 0 success, otherwise errno error code.
*
* dma_map:
*
* Callback function to be used by IB core asking the peer client to fill
* the dma address mapping for a given address range.
*
* sg_head [IN/OUT] - pointer to head of struct sg_table. The peer memory
* should fill the dma_address & dma_length for
* each scatter gather entry in the table.
*
* client_context [IN] - peer context for the allocation mapped.
*
* dma_device [IN] - the RDMA capable device which requires access to the
* peer memory.
*
* dmasync [IN] - flush in-flight DMA when the memory region is written.
* Same meaning as with host memory mapping, can be ignored if
* not relevant.
*
* nmap [OUT] - number of mapped/set entries.
*
* Return - 0 success, otherwise errno error code.
*
* dma_unmap:
*
* Callback function to be used by IB core asking the peer client to take
* relevant actions to unmap the memory.
*
* sg_head [IN] - pointer to head of struct sg_table. The peer memory
* should fill the dma_address & dma_length for
* each scatter gather entry in the table.
*
* client_context [IN] - peer context for the allocation mapped.
*
* dma_device [IN] - the RDMA capable device which requires access to the
* peer memory.
*
* Return - 0 success, otherwise errno error code.
*
* put_pages:
*
* Callback function to be used by IB core asking the peer client to remove the
* pinning from the given memory.
* It's the peer-direct equivalent of the kernel API put_page.
*
* sg_head [IN] - pointer to head of struct sg_table.
*
* client_context [IN] - peer context for that given allocation.
*
* get_page_size:
*
* Callback function to be used by IB core to query the
* peer client for the page size for the given
* allocation.
*
* sg_head [IN] - pointer to head of struct sg_table.
*
* client_context [IN] - peer context for that given allocation.
*
* Return - Page size in bytes
*
* release:
*
* Callback function to be used by IB core asking peer
* client to release all resources associated with
* previous acquire call. The call will be performed only
* for contexts that have been successfully acquired
* (i.e. acquire returned a non-zero value).
* Additionally, IB core guarentees that there will be no
* pages pinned through this context when the callback is
* called.
*
* client_context [IN] - peer context for the given allocation.
*
**/
struct peer_memory_client {
char name[IB_PEER_MEMORY_NAME_MAX];
char version[IB_PEER_MEMORY_VER_MAX];
int (*acquire)(unsigned long addr, size_t size, void *peer_mem_private_data,
char *peer_mem_name, void **client_context);
int (*get_pages)(unsigned long addr,
size_t size, int write, int force,
struct sg_table *sg_head,
void *client_context, u64 core_context);
int (*dma_map)(struct sg_table *sg_head, void *client_context,
struct device *dma_device, int dmasync, int *nmap);
int (*dma_unmap)(struct sg_table *sg_head, void *client_context,
struct device *dma_device);
void (*put_pages)(struct sg_table *sg_head, void *client_context);
unsigned long (*get_page_size)(void *client_context);
void (*release)(void *client_context);
void* (*get_context_private_data)(u64 peer_id);
void (*put_context_private_data)(void *context);
};
typedef int (*invalidate_peer_memory)(void *reg_handle, u64 core_context);
void *ib_register_peer_memory_client(const struct peer_memory_client *peer_client,
invalidate_peer_memory *invalidate_callback);
void ib_unregister_peer_memory_client(void *reg_handle);
#endif