Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

RDMA/umem: Add pinned revocable dmabuf import interface

Added an interface for importing a pinned but revocable dmabuf.
This interface can be used by drivers that are capable of revocation
so that they can import dmabufs from exporters that may require it,
such as VFIO.

This interface implements a two step process, where drivers will first
call ib_umem_dmabuf_get_pinned_revocable_and_lock() which will pin and
map the dmabuf (and provide a functional move_notify/invalidate_mappings
callback), but will return with the lock still held so that the
driver can then populate the callback via
ib_umem_dmabuf_set_revoke_locked() without races from concurrent
revocations. This scheme also allows for easier integration with drivers
that may not have actually allocated their internal MR objects at the time
of the get_pinned_revocable* call.

Signed-off-by: Jacob Moroni <jmoroni@google.com>
Link: https://patch.msgid.link/20260305170826.3803155-4-jmoroni@google.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>

authored by

Jacob Moroni and committed by
Leon Romanovsky
ff85a2eb 797291a6

+80
+61
drivers/infiniband/core/umem_dmabuf.c
··· 203 203 204 204 if (umem_dmabuf->revoked) 205 205 return; 206 + 207 + if (umem_dmabuf->pinned_revoke) 208 + umem_dmabuf->pinned_revoke(umem_dmabuf->private); 209 + 206 210 ib_umem_dmabuf_unmap_pages(umem_dmabuf); 207 211 if (umem_dmabuf->pinned) { 208 212 dma_buf_unpin(umem_dmabuf->attach); ··· 214 210 } 215 211 umem_dmabuf->revoked = 1; 216 212 } 213 + 214 + static struct dma_buf_attach_ops ib_umem_dmabuf_attach_pinned_revocable_ops = { 215 + .allow_peer2peer = true, 216 + .move_notify = ib_umem_dmabuf_revoke_locked, 217 + }; 217 218 218 219 static struct ib_umem_dmabuf * 219 220 ib_umem_dmabuf_get_pinned_and_lock(struct ib_device *device, ··· 271 262 return umem_dmabuf; 272 263 } 273 264 EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_with_dma_device); 265 + 266 + /** 267 + * ib_umem_dmabuf_get_pinned_revocable_and_lock - Map & pin a revocable dmabuf 268 + * @device: IB device. 269 + * @offset: Start offset. 270 + * @size: Length. 271 + * @fd: dmabuf fd. 272 + * @access: Access flags. 273 + * 274 + * Obtains a umem from a dmabuf for drivers/devices that can support revocation. 275 + * 276 + * Returns with dma_resv_lock held upon success. The driver must set the revoke 277 + * callback prior to unlock by calling ib_umem_dmabuf_set_revoke_locked(). 278 + * 279 + * When a revocation occurs, the revoke callback will be called. The driver must 280 + * ensure that the region is no longer accessed when the callback returns. Any 281 + * subsequent access attempts should also probably cause an AE for MRs. 282 + * 283 + * If the umem is used for an MR, the driver must ensure that the key remains in 284 + * use such that it cannot be obtained by a new region until this region is 285 + * fully deregistered (i.e., ibv_dereg_mr). If a driver needs to serialize with 286 + * revoke calls, it can use dma_resv_lock. 287 + * 288 + * If successful, then the revoke callback may be called at any time and will 289 + * also be called automatically upon ib_umem_release (serialized). The revoke 290 + * callback will be called one time at most. 291 + * 292 + * Return: A pointer to ib_umem_dmabuf on success, or an ERR_PTR on failure. 293 + */ 294 + struct ib_umem_dmabuf * 295 + ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device, 296 + unsigned long offset, size_t size, 297 + int fd, int access) 298 + { 299 + const struct dma_buf_attach_ops *ops = 300 + &ib_umem_dmabuf_attach_pinned_revocable_ops; 301 + 302 + return ib_umem_dmabuf_get_pinned_and_lock(device, device->dma_device, 303 + offset, size, fd, access, 304 + ops); 305 + } 306 + EXPORT_SYMBOL(ib_umem_dmabuf_get_pinned_revocable_and_lock); 307 + 308 + void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf, 309 + void (*revoke)(void *priv), void *priv) 310 + { 311 + dma_resv_assert_held(umem_dmabuf->attach->dmabuf->resv); 312 + 313 + umem_dmabuf->pinned_revoke = revoke; 314 + umem_dmabuf->private = priv; 315 + } 316 + EXPORT_SYMBOL(ib_umem_dmabuf_set_revoke_locked); 274 317 275 318 struct ib_umem_dmabuf *ib_umem_dmabuf_get_pinned(struct ib_device *device, 276 319 unsigned long offset,
+19
include/rdma/ib_umem.h
··· 32 32 struct scatterlist *last_sg; 33 33 unsigned long first_sg_offset; 34 34 unsigned long last_sg_trim; 35 + void (*pinned_revoke)(void *priv); 35 36 void *private; 36 37 u8 pinned : 1; 37 38 u8 revoked : 1; ··· 138 137 size_t size, int fd, 139 138 int access); 140 139 struct ib_umem_dmabuf * 140 + ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device, 141 + unsigned long offset, size_t size, 142 + int fd, int access); 143 + void ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf, 144 + void (*revoke)(void *priv), void *priv); 145 + struct ib_umem_dmabuf * 141 146 ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, 142 147 struct device *dma_device, 143 148 unsigned long offset, size_t size, ··· 195 188 { 196 189 return ERR_PTR(-EOPNOTSUPP); 197 190 } 191 + 192 + static inline struct ib_umem_dmabuf * 193 + ib_umem_dmabuf_get_pinned_revocable_and_lock(struct ib_device *device, 194 + unsigned long offset, size_t size, 195 + int fd, int access) 196 + { 197 + return ERR_PTR(-EOPNOTSUPP); 198 + } 199 + 200 + static inline void 201 + ib_umem_dmabuf_set_revoke_locked(struct ib_umem_dmabuf *umem_dmabuf, 202 + void (*revoke)(void *priv), void *priv) {} 198 203 199 204 static inline struct ib_umem_dmabuf * 200 205 ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device,