Module Name: src Committed By: riastradh Date: Sun Dec 19 00:58:04 UTC 2021
Modified Files: src/sys/external/bsd/drm2/dist/include/drm: drm_file.h src/sys/external/bsd/drm2/drm: drm_file.c Log Message: Sync drm_file.c. Prepare to convert event read lock to cv. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 \ src/sys/external/bsd/drm2/dist/include/drm/drm_file.h cvs rdiff -u -r1.1 -r1.2 src/sys/external/bsd/drm2/drm/drm_file.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/dist/include/drm/drm_file.h diff -u src/sys/external/bsd/drm2/dist/include/drm/drm_file.h:1.3 src/sys/external/bsd/drm2/dist/include/drm/drm_file.h:1.4 --- src/sys/external/bsd/drm2/dist/include/drm/drm_file.h:1.3 Sun Dec 19 00:46:23 2021 +++ src/sys/external/bsd/drm2/dist/include/drm/drm_file.h Sun Dec 19 00:58:04 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_file.h,v 1.3 2021/12/19 00:46:23 riastradh Exp $ */ +/* $NetBSD: drm_file.h,v 1.4 2021/12/19 00:58:04 riastradh Exp $ */ /* * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. @@ -332,7 +332,12 @@ struct drm_file { int event_space; /** @event_read_lock: Serializes drm_read(). */ +#ifdef __NetBSD__ + struct lwp *event_read_lock; + drm_waitqueue_t event_read_wq; +#else struct mutex event_read_lock; +#endif /** * @prime: Index: src/sys/external/bsd/drm2/drm/drm_file.c diff -u src/sys/external/bsd/drm2/drm/drm_file.c:1.1 src/sys/external/bsd/drm2/drm/drm_file.c:1.2 --- src/sys/external/bsd/drm2/drm/drm_file.c:1.1 Sun Dec 19 00:57:55 2021 +++ src/sys/external/bsd/drm2/drm/drm_file.c Sun Dec 19 00:58:04 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: drm_file.c,v 1.1 2021/12/19 00:57:55 riastradh Exp $ */ +/* $NetBSD: drm_file.c,v 1.2 2021/12/19 00:58:04 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: drm_file.c,v 1.1 2021/12/19 00:57:55 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: drm_file.c,v 1.2 2021/12/19 00:58:04 riastradh Exp $"); #include <sys/param.h> #include <sys/select.h> @@ -38,35 +38,43 @@ __KERNEL_RCSID(0, "$NetBSD: drm_file.c,v #include <drm/drmP.h> #include <drm/drm_internal.h> #include <drm/drm_legacy.h> -#include "../dist/drm/drm_legacy.h" -static int drm_open_file_master(struct drm_file *); +#include "../dist/drm/drm_crtc_internal.h" +#include "../dist/drm/drm_internal.h" +#include "../dist/drm/drm_legacy.h" -static void drm_master_release(struct drm_file *); static void drm_events_release(struct drm_file *); -static void drm_close_file_master(struct drm_file *); int drm_open_file(struct drm_file *file, void *fp, struct drm_minor *minor) { + /* + * XXX Synchronize with dist/drm/drm_file.c: drm_file_alloc, + * drm_open_helper. + */ struct drm_device *const dev = minor->dev; int ret; + bool postclose = false; file->authenticated = capable(CAP_SYS_ADMIN); /* XXX */ file->is_master = false; file->stereo_allowed = false; file->universal_planes = false; file->atomic = false; - file->allowed_master = false; + file->aspect_ratio_allowed = false; + file->writeback_connectors = false; + file->is_master = false; + file->master = NULL; file->magic = 0; + INIT_LIST_HEAD(&file->lhead); file->minor = minor; - file->lock_count = 0; /* file->object_idr is initialized by drm_gem_open. */ /* file->table_lock is initialized by drm_gem_open. */ + /* file->syncobj_idr is initialized by drm_syncobj_open. */ + /* file->syncobj_table_lock is initialized by drm_syncobj_open. */ file->filp = fp; file->driver_priv = NULL; - file->master = NULL; INIT_LIST_HEAD(&file->fbs); linux_mutex_init(&file->fbs_lock); INIT_LIST_HEAD(&file->blobs); @@ -75,9 +83,14 @@ drm_open_file(struct drm_file *file, voi INIT_LIST_HEAD(&file->event_list); file->event_space = 0x1000; /* XXX cargo-culted from Linux */ /* file->prime is initialized by drm_prime_init_file_private. */ + file->event_read_lock = NULL; + DRM_INIT_WAITQUEUE(&file->event_read_wq, "drmevtrd"); + file->lock_count = 0; if (drm_core_check_feature(dev, DRIVER_GEM)) drm_gem_open(dev, file); + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + drm_syncobj_open(file); if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_prime_init_file_private(&file->prime); @@ -87,9 +100,11 @@ drm_open_file(struct drm_file *file, voi goto fail0; } - ret = drm_open_file_master(file); - if (ret) - goto fail1; + if (drm_is_primary_client(file)) { + ret = drm_master_open(file); + if (ret) + goto fail1; + } mutex_lock(&dev->struct_mutex); list_add(&file->lhead, &dev->filelist); @@ -98,210 +113,95 @@ drm_open_file(struct drm_file *file, voi /* Success! */ return 0; -fail1: /* - * XXX This error branch needs scrutiny, but Linux's error - * branches are incomprehensible and look wronger. - */ - if (dev->driver->preclose) +fail1: + postclose = true; + if (drm_core_check_feature(dev, DRIVER_LEGACY) && + dev->driver->preclose) (*dev->driver->preclose)(dev, file); - if (dev->driver->postclose) - (*dev->driver->postclose)(dev, file); fail0: if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_prime_destroy_file_private(&file->prime); + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + drm_syncobj_release(file); if (drm_core_check_feature(dev, DRIVER_GEM)) drm_gem_release(dev, file); - return ret; -} - -int -drm_new_set_master(struct drm_device *dev, struct drm_file *file) -{ - struct drm_master *old_master; - int ret; - - KASSERT(mutex_is_locked(&dev->master_mutex)); - KASSERT(file->minor->type == DRM_MINOR_LEGACY); - KASSERT(file->minor->master == NULL); - - file->minor->master = drm_master_create(file->minor); - if (file->minor->master == NULL) { - ret = -ENOMEM; - goto fail0; - } - - /* - * Save the old master, to drop a reference later if all goes - * well, and get a reference to the new one. - */ - old_master = file->master; - file->master = drm_master_get(file->minor->master); - - /* Invoke the driver callbacks master_create and master_set. */ - if (dev->driver->master_create) { - ret = (*dev->driver->master_create)(dev, file->minor->master); - if (ret) - goto fail1; - } - - if (dev->driver->master_set) { - ret = (*dev->driver->master_set)(dev, file, true); - if (ret) - goto fail1; - } - - /* - * Mark ourselves as an authenticated master, and allowed to - * set a new master. - */ - file->is_master = 1; - file->allowed_master = 1; - file->authenticated = 1; - - /* If there was an old master, release it now. */ - if (old_master) - drm_master_put(&old_master); - - /* Success! */ - return 0; - -fail1: - /* Release the master we just created. */ - drm_master_put(&file->minor->master); - KASSERT(file->minor->master == NULL); - /* Release the reference we just added in the file. */ - drm_master_put(&file->master); - KASSERT(file->master == NULL); - /* Restore the old master if there was one. */ - file->master = old_master; -fail0: KASSERT(ret); - return ret; -} - -static int -drm_open_file_master(struct drm_file *file) -{ - struct drm_device *const dev = file->minor->dev; - int ret; - - /* If this is not the legacy device, there are no masters. */ - if (file->minor->type != DRM_MINOR_LEGACY) - return 0; - - mutex_lock(&dev->master_mutex); - if (file->minor->master != NULL) { - /* - * If the minor already has a master, get a reference - * to it. - */ - file->master = drm_master_get(file->minor->master); - ret = 0; - } else { - /* - * Otherwise, automatically behave as though we had - * just done setmaster. - */ - ret = drm_new_set_master(dev, file); - } - mutex_unlock(&dev->master_mutex); - + if (postclose && + drm_core_check_feature(dev, DRIVER_LEGACY) && + dev->driver->postclose) + (*dev->driver->postclose)(dev, file); + KASSERT(file->event_read_lock == NULL); + DRM_DESTROY_WAITQUEUE(&file->event_read_wq); + seldestroy(&file->event_selq); + DRM_DESTROY_WAITQUEUE(&file->event_wait); + linux_mutex_destroy(&file->fbs_lock); return ret; } void drm_close_file(struct drm_file *file) { + /* XXX Synchronize with dist/drm/drm_file.c, drm_file_free. */ struct drm_minor *const minor = file->minor; struct drm_device *const dev = minor->dev; - mutex_lock(&dev->struct_mutex); - list_del(&file->lhead); - if (file->magic) - idr_remove(&file->master->magic_map, file->magic); - mutex_unlock(&dev->struct_mutex); - - if (dev->driver->preclose) + if (drm_core_check_feature(dev, DRIVER_LEGACY) && + dev->driver->preclose) (*dev->driver->preclose)(dev, file); - if (minor->master) - drm_master_release(file); + if (drm_core_check_feature(dev, DRIVER_LEGACY)) + drm_legacy_lock_release(dev, file->filp); + if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) drm_legacy_reclaim_buffers(dev, file); + drm_events_release(file); + if (drm_core_check_feature(dev, DRIVER_MODESET)) { drm_fb_release(file); drm_property_destroy_user_blobs(dev, file); } + + if (drm_core_check_feature(dev, DRIVER_SYNCOBJ)) + drm_syncobj_release(file); + if (drm_core_check_feature(dev, DRIVER_GEM)) drm_gem_release(dev, file); + drm_legacy_ctxbitmap_flush(dev, file); - drm_close_file_master(file); + + if (drm_is_primary_client(file)) + drm_master_release(file); if (dev->driver->postclose) - (*dev->driver->postclose)(dev, file); + dev->driver->postclose(dev, file); if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_prime_destroy_file_private(&file->prime); + KASSERT(list_empty(&file->event_list)); + seldestroy(&file->event_selq); DRM_DESTROY_WAITQUEUE(&file->event_wait); linux_mutex_destroy(&file->fbs_lock); } static void -drm_master_release(struct drm_file *file) -{ - - /* - * XXX I think this locking concept is wrong -- we need to hold - * file->master->lock.spinlock across the two calls to - * drm_legacy_i_have_hw_lock and drm_legacy_lock_free. - */ - if (drm_legacy_i_have_hw_lock(file->minor->dev, file)) - drm_legacy_lock_free(&file->master->lock, - _DRM_LOCKING_CONTEXT(file->master->lock.hw_lock->lock)); -} - -static void drm_events_release(struct drm_file *file) { + /* XXX Synchronize with dist/drm/drm_file.c, drm_events_release. */ struct drm_device *const dev = file->minor->dev; - struct drm_pending_vblank_event *vblank, *vblank_next; struct drm_pending_event *event, *event_next; - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); - list_for_each_entry_safe(vblank, vblank_next, &dev->vblank_event_list, - base.link) { - if (vblank->base.file_priv == file) { - list_del(&vblank->base.link); - drm_vblank_put(dev, vblank->pipe); - (*vblank->base.destroy)(&vblank->base); - } + spin_lock(&dev->event_lock); + list_for_each_entry_safe(event, event_next, &file->pending_event_list, + pending_link) { + KASSERT(event->file_priv == file); + list_del(&event->pending_link); + event->file_priv = NULL; } list_for_each_entry_safe(event, event_next, &file->event_list, link) { - (*event->destroy)(event); - } - - spin_unlock_irqrestore(&dev->event_lock, flags); -} - -static void -drm_close_file_master(struct drm_file *file) -{ - struct drm_device *const dev = file->minor->dev; - - mutex_lock(&dev->master_mutex); - if (file->is_master) { - if (file->minor->master == file->master) { - if (dev->driver->master_drop) - (*dev->driver->master_drop)(dev, file, true); - drm_master_put(&file->minor->master); - } + list_del(&event->link); + kfree(event); } - if (file->master != NULL) - drm_master_put(&file->master); - file->is_master = 0; - mutex_unlock(&dev->master_mutex); + spin_unlock(&dev->event_lock); }