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);
 }

Reply via email to