// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright(c) 2016 Intel Corporation. */ #include <linux/slab.h> #include <linux/vmalloc.h> #include <rdma/ib_umem.h> #include <rdma/rdma_vt.h> #include "vt.h" #include "mr.h" #include "trace.h" /** * rvt_driver_mr_init - Init MR resources per driver * @rdi: rvt dev struct * * Do any intilization needed when a driver registers with rdmavt. * * Return: 0 on success or errno on failure */ int rvt_driver_mr_init(struct rvt_dev_info *rdi) { … } /** * rvt_mr_exit - clean up MR * @rdi: rvt dev structure * * called when drivers have unregistered or perhaps failed to register with us */ void rvt_mr_exit(struct rvt_dev_info *rdi) { … } static void rvt_deinit_mregion(struct rvt_mregion *mr) { … } static void __rvt_mregion_complete(struct percpu_ref *ref) { … } static int rvt_init_mregion(struct rvt_mregion *mr, struct ib_pd *pd, int count, unsigned int percpu_flags) { … } /** * rvt_alloc_lkey - allocate an lkey * @mr: memory region that this lkey protects * @dma_region: 0->normal key, 1->restricted DMA key * * Returns 0 if successful, otherwise returns -errno. * * Increments mr reference count as required. * * Sets the lkey field mr for non-dma regions. * */ static int rvt_alloc_lkey(struct rvt_mregion *mr, int dma_region) { … } /** * rvt_free_lkey - free an lkey * @mr: mr to free from tables */ static void rvt_free_lkey(struct rvt_mregion *mr) { … } static struct rvt_mr *__rvt_alloc_mr(int count, struct ib_pd *pd) { … } static void __rvt_free_mr(struct rvt_mr *mr) { … } /** * rvt_get_dma_mr - get a DMA memory region * @pd: protection domain for this memory region * @acc: access flags * * Return: the memory region on success, otherwise returns an errno. */ struct ib_mr *rvt_get_dma_mr(struct ib_pd *pd, int acc) { … } /** * rvt_reg_user_mr - register a userspace memory region * @pd: protection domain for this memory region * @start: starting userspace address * @length: length of region to register * @virt_addr: associated virtual address * @mr_access_flags: access flags for this memory region * @udata: unused by the driver * * Return: the memory region on success, otherwise returns an errno. */ struct ib_mr *rvt_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, u64 virt_addr, int mr_access_flags, struct ib_udata *udata) { … } /** * rvt_dereg_clean_qp_cb - callback from iterator * @qp: the qp * @v: the mregion (as u64) * * This routine fields the callback for all QPs and * for QPs in the same PD as the MR will call the * rvt_qp_mr_clean() to potentially cleanup references. */ static void rvt_dereg_clean_qp_cb(struct rvt_qp *qp, u64 v) { … } /** * rvt_dereg_clean_qps - find QPs for reference cleanup * @mr: the MR that is being deregistered * * This routine iterates RC QPs looking for references * to the lkey noted in mr. */ static void rvt_dereg_clean_qps(struct rvt_mregion *mr) { … } /** * rvt_check_refs - check references * @mr: the megion * @t: the caller identification * * This routine checks MRs holding a reference during * when being de-registered. * * If the count is non-zero, the code calls a clean routine then * waits for the timeout for the count to zero. */ static int rvt_check_refs(struct rvt_mregion *mr, const char *t) { … } /** * rvt_mr_has_lkey - is MR * @mr: the mregion * @lkey: the lkey */ bool rvt_mr_has_lkey(struct rvt_mregion *mr, u32 lkey) { … } /** * rvt_ss_has_lkey - is mr in sge tests * @ss: the sge state * @lkey: the lkey * * This code tests for an MR in the indicated * sge state. */ bool rvt_ss_has_lkey(struct rvt_sge_state *ss, u32 lkey) { … } /** * rvt_dereg_mr - unregister and free a memory region * @ibmr: the memory region to free * @udata: unused by the driver * * Note that this is called to free MRs created by rvt_get_dma_mr() * or rvt_reg_user_mr(). * * Returns 0 on success. */ int rvt_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) { … } /** * rvt_alloc_mr - Allocate a memory region usable with the * @pd: protection domain for this memory region * @mr_type: mem region type * @max_num_sg: Max number of segments allowed * * Return: the memory region on success, otherwise return an errno. */ struct ib_mr *rvt_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 max_num_sg) { … } /** * rvt_set_page - page assignment function called by ib_sg_to_pages * @ibmr: memory region * @addr: dma address of mapped page * * Return: 0 on success */ static int rvt_set_page(struct ib_mr *ibmr, u64 addr) { … } /** * rvt_map_mr_sg - map sg list and set it the memory region * @ibmr: memory region * @sg: dma mapped scatterlist * @sg_nents: number of entries in sg * @sg_offset: offset in bytes into sg * * Overwrite rvt_mr length with mr length calculated by ib_sg_to_pages. * * Return: number of sg elements mapped to the memory region */ int rvt_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, unsigned int *sg_offset) { … } /** * rvt_fast_reg_mr - fast register physical MR * @qp: the queue pair where the work request comes from * @ibmr: the memory region to be registered * @key: updated key for this memory region * @access: access flags for this memory region * * Returns 0 on success. */ int rvt_fast_reg_mr(struct rvt_qp *qp, struct ib_mr *ibmr, u32 key, int access) { … } EXPORT_SYMBOL(…); /** * rvt_invalidate_rkey - invalidate an MR rkey * @qp: queue pair associated with the invalidate op * @rkey: rkey to invalidate * * Returns 0 on success. */ int rvt_invalidate_rkey(struct rvt_qp *qp, u32 rkey) { … } EXPORT_SYMBOL(…); /** * rvt_sge_adjacent - is isge compressible * @last_sge: last outgoing SGE written * @sge: SGE to check * * If adjacent will update last_sge to add length. * * Return: true if isge is adjacent to last sge */ static inline bool rvt_sge_adjacent(struct rvt_sge *last_sge, struct ib_sge *sge) { … } /** * rvt_lkey_ok - check IB SGE for validity and initialize * @rkt: table containing lkey to check SGE against * @pd: protection domain * @isge: outgoing internal SGE * @last_sge: last outgoing SGE written * @sge: SGE to check * @acc: access flags * * Check the IB SGE for validity and initialize our internal version * of it. * * Increments the reference count when a new sge is stored. * * Return: 0 if compressed, 1 if added , otherwise returns -errno. */ int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd, struct rvt_sge *isge, struct rvt_sge *last_sge, struct ib_sge *sge, int acc) { … } EXPORT_SYMBOL(…); /** * rvt_rkey_ok - check the IB virtual address, length, and RKEY * @qp: qp for validation * @sge: SGE state * @len: length of data * @vaddr: virtual address to place data * @rkey: rkey to check * @acc: access flags * * Return: 1 if successful, otherwise 0. * * increments the reference count upon success */ int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge, u32 len, u64 vaddr, u32 rkey, int acc) { … } EXPORT_SYMBOL(…);