libdrm full analysis ten - full source code analysis (7)

Continued from the previous article: Full analysis of libdrm 9 - Full analysis of source code (6)

This article refers to the following blog posts:

DRM driver development (VKMS)

Thank you very much!

This article continues to explain the actual function macro definition in include/drm/drm.h.

11. DRM_IOCTL_GEM_FLINK

The 11th macro is DRM_IOCTL_GEM_FLINK, the corresponding code is as follows:

#define DRM_IOCTL_GEM_FLINK		DRM_IOWR(0x0a, struct drm_gem_flink)

Combined with the final definition of _IOWR(type,nr,size) in the previous article, the following code is obtained:

#define DRM_IOCTL_GEM_FLINK		( ((3)  << 30) | (('d') << 8) | ((0x0a)   << 0) | ((sizeof(struct drm_gem_flink)) << 16) )

struct drm_gem_flink is defined in the same file (include/drm/drm.h), the code is as follows:

/* DRM_IOCTL_GEM_FLINK ioctl argument type */
struct drm_gem_flink {
	/** Handle for the object being named */
	__u32 handle;

	/** Returned global name */
	__u32 name;
};

The meaning code comments of each member in the drm_gem_flink structure are clearly described, so there is no need to repeat them here.

Although DRM_IOCTL_GEM_FLINK does not have a direct corresponding Userspace API (that is, there is no corresponding package), there are many places in the libdrm source code that directly call it.

  • amdgpu/amdgpu_bo.c中:
static int amdgpu_bo_export_flink(amdgpu_bo_handle bo)
{
	struct drm_gem_flink flink;
	int fd, dma_fd;
	uint32_t handle;
	int r;

	fd = bo->dev->fd;
	handle = bo->handle;
	if (bo->flink_name)
		return 0;


	……
	memset(&flink, 0, sizeof(flink));
	flink.handle = handle;

	r = drmIoctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
	if (r)
		return r;

    ……

	return r;
}
  • etnaviv/etnaviv_bo.c中:
/* get the global flink/DRI2 buffer name */
drm_public int etna_bo_get_name(struct etna_bo *bo, uint32_t *name)
{
	if (!bo->name) {
		struct drm_gem_flink req = {
			.handle = bo->handle,
		};
		int ret;

		ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
		if (ret) {
			return ret;
		}

		pthread_mutex_lock(&table_lock);
		set_name(bo, req.name);
		pthread_mutex_unlock(&table_lock);
		bo->reuse = 0;
	}

	*name = bo->name;

	return 0;
}
  • exynos/exynos_drm.c中:
/*
 * Get a gem global object name from a gem object handle.
 *
 * @bo: a exynos buffer object including gem handle.
 * @name: a gem global object name to be got by kernel driver.
 *
 * this interface is used to get a gem global object name from a gem object
 * handle to a buffer that wants to share it with another process.
 *
 * if true, return 0 else negative.
 */
drm_public int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
{
	if (!bo->name) {
		struct drm_gem_flink req = {
			.handle = bo->handle,
		};
		int ret;

		ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
		if (ret) {
			fprintf(stderr, "failed to get gem global name[%s].\n",
					strerror(errno));
			return ret;
		}

		bo->name = req.name;
	}

	*name = bo->name;

	return 0;
}
  • freedreno/freedreno_bo.c中:
drm_public int fd_bo_get_name(struct fd_bo *bo, uint32_t *name)
{
	if (!bo->name) {
		struct drm_gem_flink req = {
				.handle = bo->handle,
		};
		int ret;

		ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
		if (ret) {
			return ret;
		}

		pthread_mutex_lock(&table_lock);
		set_name(bo, req.name);
		pthread_mutex_unlock(&table_lock);
		bo->bo_reuse = NO_CACHE;
	}

	*name = bo->name;

	return 0;
}
  • intel/intel_bufmgr_gem.c中:
static int
drm_intel_gem_bo_flink(drm_intel_bo *bo, uint32_t * name)
{
	drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr;
	drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;

	if (!bo_gem->global_name) {
		struct drm_gem_flink flink;

		memclear(flink);
		flink.handle = bo_gem->gem_handle;
		if (drmIoctl(bufmgr_gem->fd, DRM_IOCTL_GEM_FLINK, &flink))
			return -errno;

		pthread_mutex_lock(&bufmgr_gem->lock);
		if (!bo_gem->global_name) {
			bo_gem->global_name = flink.name;
			bo_gem->reusable = false;

			HASH_ADD(name_hh, bufmgr_gem->name_table,
				 global_name, sizeof(bo_gem->global_name),
				 bo_gem);
		}
		pthread_mutex_unlock(&bufmgr_gem->lock);
	}

	*name = bo_gem->global_name;
	return 0;
}
  • new/new.c中:
drm_public int
nouveau_bo_name_get(struct nouveau_bo *bo, uint32_t *name)
{
	struct drm_gem_flink req = { .handle = bo->handle };
	struct nouveau_drm *drm = nouveau_drm(&bo->device->object);
	struct nouveau_bo_priv *nvbo = nouveau_bo(bo);

	*name = nvbo->name;
	if (!*name) {
		int ret = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &req);

		if (ret) {
			*name = 0;
			return ret;
		}
		nvbo->name = *name = req.name;

		nouveau_bo_make_global(nvbo);
	}
	return 0;
}
  • In omap/omap_drm.c:
/* get the global flink/DRI2 buffer name */
drm_public int omap_bo_get_name(struct omap_bo *bo, uint32_t *name)
{
	if (!bo->name) {
		struct drm_gem_flink req = {
				.handle = bo->handle,
		};
		int ret;

		ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
		if (ret) {
			return ret;
		}

		bo->name = req.name;
	}

	*name = bo->name;

	return 0;
}
  • In radeon/radeon_bo_gem.c:
drm_public int
radeon_gem_get_kernel_name(struct radeon_bo *bo, uint32_t *name)
{
    struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
    struct radeon_bo_int *boi = (struct radeon_bo_int *)bo;
    struct drm_gem_flink flink;
    int r;

    if (bo_gem->name) {
        *name = bo_gem->name;
        return 0;
    }
    flink.handle = bo->handle;
    r = drmIoctl(boi->bom->fd, DRM_IOCTL_GEM_FLINK, &flink);
    if (r) {
        return r;
    }
    bo_gem->name = flink.name;
    *name = flink.name;
    return 0;
}
  • tegra/tegra.c中:
drm_public int drm_tegra_bo_get_name(struct drm_tegra_bo *bo, uint32_t *name)
{
    struct drm_tegra *drm = bo->drm;
    struct drm_gem_flink args;
    int err;

    memset(&args, 0, sizeof(args));
    args.handle = bo->handle;

    err = drmIoctl(drm->fd, DRM_IOCTL_GEM_FLINK, &args);
    if (err < 0)
        return err;

    if (name)
        *name = args.name;

    return 0;
}

By the way, all kinds of graphics cards are listed here. Each graphics card will call drmIoctl corresponding to DRM_IOCTL_GEM_FLINK.

The remaining macro definitions will continue to be analyzed in subsequent articles.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/132470768