1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2 /* 3 * Copyright (c) 2007 Cisco Systems. All rights reserved. 4 */ 5 6 #ifndef IB_UMEM_H 7 #define IB_UMEM_H 8 9 #include <linux/list.h> 10 #include <linux/scatterlist.h> 11 #include <linux/workqueue.h> 12 #include <rdma/ib_verbs.h> 13 14 struct ib_ucontext; 15 struct ib_umem_odp; 16 17 struct ib_umem { 18 struct ib_device *ibdev; 19 struct mm_struct *owning_mm; 20 size_t length; 21 unsigned long address; 22 u32 writable : 1; 23 u32 is_odp : 1; 24 struct work_struct work; 25 struct sg_table sg_head; 26 int nmap; 27 unsigned int sg_nents; 28 }; 29 30 /* Returns the offset of the umem start relative to the first page. */ 31 static inline int ib_umem_offset(struct ib_umem *umem) 32 { 33 return umem->address & ~PAGE_MASK; 34 } 35 36 static inline size_t ib_umem_num_pages(struct ib_umem *umem) 37 { 38 return (ALIGN(umem->address + umem->length, PAGE_SIZE) - 39 ALIGN_DOWN(umem->address, PAGE_SIZE)) >> 40 PAGE_SHIFT; 41 } 42 43 #ifdef CONFIG_INFINIBAND_USER_MEM 44 45 struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, 46 size_t size, int access); 47 void ib_umem_release(struct ib_umem *umem); 48 int ib_umem_page_count(struct ib_umem *umem); 49 int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset, 50 size_t length); 51 unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, 52 unsigned long pgsz_bitmap, 53 unsigned long virt); 54 55 #else /* CONFIG_INFINIBAND_USER_MEM */ 56 57 #include <linux/err.h> 58 59 static inline struct ib_umem *ib_umem_get(struct ib_device *device, 60 unsigned long addr, size_t size, 61 int access) 62 { 63 return ERR_PTR(-EINVAL); 64 } 65 static inline void ib_umem_release(struct ib_umem *umem) { } 66 static inline int ib_umem_page_count(struct ib_umem *umem) { return 0; } 67 static inline int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset, 68 size_t length) { 69 return -EINVAL; 70 } 71 static inline int ib_umem_find_best_pgsz(struct ib_umem *umem, 72 unsigned long pgsz_bitmap, 73 unsigned long virt) { 74 return -EINVAL; 75 } 76 77 #endif /* CONFIG_INFINIBAND_USER_MEM */ 78 79 #endif /* IB_UMEM_H */ 80