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.

drm/panthor: Provide a custom dma_buf implementation

Before we introduce cached CPU mappings, we want a dma_buf
implementation satisfying synchronization requests around CPU
accesses coming from a dma_buf exported by our driver. Let's
provide our own implementation relying on the default
gem_shmem_prime helpers designed for that purpose.

v5:
- New patch

v6:
- Collect R-b

v7:
- Hand-roll the dma_buf sync/import logic (was previously done by
generic prime/shmem helpers)

v8:
- No changes

Reviewed-by: Steven Price <steven.price@arm.com>
Link: https://patch.msgid.link/20251208100841.730527-2-boris.brezillon@collabora.com
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>

+122 -1
+1
drivers/gpu/drm/panthor/panthor_drv.c
··· 1623 1623 1624 1624 .gem_create_object = panthor_gem_create_object, 1625 1625 .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table, 1626 + .gem_prime_import = panthor_gem_prime_import, 1626 1627 #ifdef CONFIG_DEBUG_FS 1627 1628 .debugfs_init = panthor_debugfs_init, 1628 1629 #endif
+117 -1
drivers/gpu/drm/panthor/panthor_gem.c
··· 202 202 return ERR_PTR(ret); 203 203 } 204 204 205 + static struct sg_table * 206 + panthor_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, 207 + enum dma_data_direction dir) 208 + { 209 + struct sg_table *sgt = drm_gem_map_dma_buf(attach, dir); 210 + 211 + if (!IS_ERR(sgt)) 212 + attach->priv = sgt; 213 + 214 + return sgt; 215 + } 216 + 217 + static void 218 + panthor_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, 219 + struct sg_table *sgt, 220 + enum dma_data_direction dir) 221 + { 222 + attach->priv = NULL; 223 + drm_gem_unmap_dma_buf(attach, sgt, dir); 224 + } 225 + 226 + static int 227 + panthor_gem_prime_begin_cpu_access(struct dma_buf *dma_buf, 228 + enum dma_data_direction dir) 229 + { 230 + struct drm_gem_object *obj = dma_buf->priv; 231 + struct drm_device *dev = obj->dev; 232 + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 233 + struct dma_buf_attachment *attach; 234 + 235 + dma_resv_lock(obj->resv, NULL); 236 + if (shmem->sgt) 237 + dma_sync_sgtable_for_cpu(dev->dev, shmem->sgt, dir); 238 + 239 + if (shmem->vaddr) 240 + invalidate_kernel_vmap_range(shmem->vaddr, shmem->base.size); 241 + 242 + list_for_each_entry(attach, &dma_buf->attachments, node) { 243 + struct sg_table *sgt = attach->priv; 244 + 245 + if (sgt) 246 + dma_sync_sgtable_for_cpu(attach->dev, sgt, dir); 247 + } 248 + dma_resv_unlock(obj->resv); 249 + 250 + return 0; 251 + } 252 + 253 + static int 254 + panthor_gem_prime_end_cpu_access(struct dma_buf *dma_buf, 255 + enum dma_data_direction dir) 256 + { 257 + struct drm_gem_object *obj = dma_buf->priv; 258 + struct drm_device *dev = obj->dev; 259 + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 260 + struct dma_buf_attachment *attach; 261 + 262 + dma_resv_lock(obj->resv, NULL); 263 + list_for_each_entry(attach, &dma_buf->attachments, node) { 264 + struct sg_table *sgt = attach->priv; 265 + 266 + if (sgt) 267 + dma_sync_sgtable_for_device(attach->dev, sgt, dir); 268 + } 269 + 270 + if (shmem->vaddr) 271 + flush_kernel_vmap_range(shmem->vaddr, shmem->base.size); 272 + 273 + if (shmem->sgt) 274 + dma_sync_sgtable_for_device(dev->dev, shmem->sgt, dir); 275 + 276 + dma_resv_unlock(obj->resv); 277 + return 0; 278 + } 279 + 280 + static const struct dma_buf_ops panthor_dma_buf_ops = { 281 + .attach = drm_gem_map_attach, 282 + .detach = drm_gem_map_detach, 283 + .map_dma_buf = panthor_gem_prime_map_dma_buf, 284 + .unmap_dma_buf = panthor_gem_prime_unmap_dma_buf, 285 + .release = drm_gem_dmabuf_release, 286 + .mmap = drm_gem_dmabuf_mmap, 287 + .vmap = drm_gem_dmabuf_vmap, 288 + .vunmap = drm_gem_dmabuf_vunmap, 289 + .begin_cpu_access = panthor_gem_prime_begin_cpu_access, 290 + .end_cpu_access = panthor_gem_prime_end_cpu_access, 291 + }; 292 + 205 293 static struct dma_buf * 206 294 panthor_gem_prime_export(struct drm_gem_object *obj, int flags) 207 295 { 296 + struct drm_device *dev = obj->dev; 297 + struct dma_buf_export_info exp_info = { 298 + .exp_name = KBUILD_MODNAME, 299 + .owner = THIS_MODULE, 300 + .ops = &panthor_dma_buf_ops, 301 + .size = obj->size, 302 + .flags = flags, 303 + .priv = obj, 304 + .resv = obj->resv, 305 + }; 306 + 208 307 /* We can't export GEMs that have an exclusive VM. */ 209 308 if (to_panthor_bo(obj)->exclusive_vm_root_gem) 210 309 return ERR_PTR(-EINVAL); 211 310 212 - return drm_gem_prime_export(obj, flags); 311 + return drm_gem_dmabuf_export(dev, &exp_info); 312 + } 313 + 314 + struct drm_gem_object * 315 + panthor_gem_prime_import(struct drm_device *dev, 316 + struct dma_buf *dma_buf) 317 + { 318 + struct drm_gem_object *obj = dma_buf->priv; 319 + 320 + if (dma_buf->ops == &panthor_dma_buf_ops && obj->dev == dev) { 321 + /* Importing dmabuf exported from our own gem increases 322 + * refcount on gem itself instead of f_count of dmabuf. 323 + */ 324 + drm_gem_object_get(obj); 325 + return obj; 326 + } 327 + 328 + return drm_gem_prime_import(dev, dma_buf); 213 329 } 214 330 215 331 static enum drm_gem_object_status panthor_gem_status(struct drm_gem_object *obj)
+4
drivers/gpu/drm/panthor/panthor_gem.h
··· 149 149 void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label); 150 150 void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label); 151 151 152 + struct drm_gem_object * 153 + panthor_gem_prime_import(struct drm_device *dev, 154 + struct dma_buf *dma_buf); 155 + 152 156 static inline u64 153 157 panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo) 154 158 {