2012/12/1 Daniel Vetter <daniel@xxxxxxxx>
On Sat, Dec 1, 2012 at 1:11 PM, Daniel Vetter <daniel@xxxxxxxx> wrote:Now with link to testcase ....
> I've quickly implemented a testcase for what I believe is your
> use-case (i.e. sharing between 3 different open drm files, where we
> close the gem handle in the first fd before we open the flink name
> again using the 3rd drm fd handle). It seems to work.
http://cgit.freedesktop.org/xorg/app/intel-gpu-tools/commit/?id=6daae8bcb6b4a930c9677f87fa24675581b69072
Cheers, Daniel
I have checked the above testcase and I found out there was my missing point.
The missing point is that when drm_gem_handle_create() is called by drm_gem_open_ioctl(), obj->handle_count also is increased.
As you mentioned, it seems like that our user side has some bug somewhere. Actually we had tested this on Xorg so this is complicated a little bit.
Thanks for your checking. :)
Thanks,
Inki Dae
And below addes my comments on your codes.
/* obj->handle_count = 1, obj->refcount = 1 */
ret = ioctl(fd2, DRM_IOCTL_I915_GEM_CREATE, &create);
assert(ret == 0);
ret = ioctl(fd2, DRM_IOCTL_I915_GEM_CREATE, &create);
assert(ret == 0);
flink.handle = create.handle;
/* obj->handle_count = 1, obj->refcount = 2, flink name is allocated */
/* flink_ioctl just increases only obj->refcount. */
ret = ioctl(fd2, DRM_IOCTL_GEM_FLINK, &flink);
assert(ret == 0);
/* obj->handle_count = 1, obj->refcount = 2, flink name is allocated */
/* flink_ioctl just increases only obj->refcount. */
ret = ioctl(fd2, DRM_IOCTL_GEM_FLINK, &flink);
assert(ret == 0);
gem_open.name = flink.name;
/* obj->handle_count = 2, obj->refcount = 3 */
/* drm_gem_handle_create() increases obj->handle_count and obj->refcount. This was my missing point. */
ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &gem_open);
assert(ret == 0);
assert(gem_open.handle != 0);
/* obj->handle_count = 2, obj->refcount = 3 */
/* drm_gem_handle_create() increases obj->handle_count and obj->refcount. This was my missing point. */
ret = ioctl(fd, DRM_IOCTL_GEM_OPEN, &gem_open);
assert(ret == 0);
assert(gem_open.handle != 0);
/* obj->handle_count = 1, obj->refcount = 2 */
/* obj->handle_count = 1 so flink name isn't released */
close(fd2);
fd2 = drm_open_any();
/* obj->handle_count = 1 so flink name isn't released */
close(fd2);
fd2 = drm_open_any();
gem_open.name = flink.name;
/* obj->handle_count = 2, obj->refcount = 3 */
ret = ioctl(fd2, DRM_IOCTL_GEM_OPEN, &gem_open);
assert(ret == 0);
assert(gem_open.handle != 0);
}
/* obj->handle_count = 2, obj->refcount = 3 */
ret = ioctl(fd2, DRM_IOCTL_GEM_OPEN, &gem_open);
assert(ret == 0);
assert(gem_open.handle != 0);
}
And codes I added to release gem like below,
/* obj->handle_count = 1, obj->refcount = 2 */
ioctl(fd2, XXX_GEM_CLOSE, handle)
/* obj->handle_count = 0, obj->refcount = 1 when flink name is released and then obj->refcount = 0 so gem object can be released */
ioctl(fd, XXX_GEM_CLOSE, handle)
/* obj->handle_count = 1, obj->refcount = 2 */
ioctl(fd2, XXX_GEM_CLOSE, handle)
/* obj->handle_count = 0, obj->refcount = 1 when flink name is released and then obj->refcount = 0 so gem object can be released */
ioctl(fd, XXX_GEM_CLOSE, handle)
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel