[PATCH 047/156] drm/nouveau/nvkm: detach user handling from nvkm_disp

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:38:13 UTC 2024


- preparation for upcoming patches
- open-code current nvkm_udisp() macro

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 .../drm/nouveau/include/nvkm/engine/disp.h    |  4 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/base.c   |  2 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/chan.c   | 17 +++++----
 .../gpu/drm/nouveau/nvkm/engine/disp/gv100.c  |  3 +-
 .../gpu/drm/nouveau/nvkm/engine/disp/priv.h   |  1 -
 .../gpu/drm/nouveau/nvkm/engine/disp/uconn.c  | 11 +++---
 .../gpu/drm/nouveau/nvkm/engine/disp/udisp.c  | 37 ++++++++++++-------
 .../gpu/drm/nouveau/nvkm/engine/disp/udisp.h  | 11 ++++++
 .../gpu/drm/nouveau/nvkm/engine/disp/uhead.c  | 11 +++---
 .../gpu/drm/nouveau/nvkm/engine/disp/uoutp.c  | 11 +++---
 10 files changed, 66 insertions(+), 42 deletions(-)
 create mode 100644 drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
index 3e8db8280e2a..e954c36630f0 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
@@ -65,8 +65,8 @@ struct nvkm_disp {
 
 	struct {
 		spinlock_t lock;
-		struct nvkm_object object;
-	} client;
+		bool allocated;
+	} user;
 };
 
 int nv04_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index b24eb1e560bc..e93646d53378 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -240,7 +240,7 @@ nvkm_disp_new_(const struct nvkm_disp_func *func, struct nvkm_device *device,
 	INIT_LIST_HEAD(&disp->iors);
 	INIT_LIST_HEAD(&disp->outps);
 	INIT_LIST_HEAD(&disp->conns);
-	spin_lock_init(&disp->client.lock);
+	spin_lock_init(&disp->user.lock);
 
 	ret = nvkm_engine_ctor(&nvkm_disp, device, type, inst, true, &disp->engine);
 	if (ret) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c
index 4e43ee383c34..25fe9946957f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c
@@ -152,10 +152,10 @@ nvkm_disp_chan_dtor(struct nvkm_object *object)
 	struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
 	struct nvkm_disp *disp = chan->disp;
 
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	if (disp->chan[chan->chid.user] == chan)
 		disp->chan[chan->chid.user] = NULL;
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 
 	nvkm_memory_unref(&chan->memory);
 	return chan;
@@ -213,21 +213,22 @@ nvkm_disp_chan_new_(struct nvkm_disp *disp, int nr, const struct nvkm_oclass *oc
 			return ret;
 	}
 
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	if (disp->chan[chan->chid.user]) {
-		spin_unlock(&disp->client.lock);
+		spin_unlock(&disp->user.lock);
 		return -EBUSY;
 	}
 	disp->chan[chan->chid.user] = chan;
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return 0;
 }
 
+#include "udisp.h"
 int
 nvkm_disp_wndw_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
 		   struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 
 	return nvkm_disp_chan_new_(disp, disp->wndw.nr, oclass, argv, argc, pobject);
 }
@@ -236,7 +237,7 @@ int
 nvkm_disp_chan_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
 		   struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 
 	return nvkm_disp_chan_new_(disp, disp->head.nr, oclass, argv, argc, pobject);
 }
@@ -245,7 +246,7 @@ int
 nvkm_disp_core_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
 		   struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 
 	return nvkm_disp_chan_new_(disp, 1, oclass, argv, argc, pobject);
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
index cfa3698d3a2f..5787fd26e5c7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
@@ -815,11 +815,12 @@ gv100_disp_caps = {
 	.map = gv100_disp_caps_map,
 };
 
+#include "udisp.h"
 int
 gv100_disp_caps_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
 		    struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 	struct gv100_disp_caps *caps;
 
 	if (!(caps = kzalloc(sizeof(*caps), GFP_KERNEL)))
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
index a3fd7cb7c488..6f0b119dfd90 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: MIT */
 #ifndef __NVKM_DISP_PRIV_H__
 #define __NVKM_DISP_PRIV_H__
-#define nvkm_udisp(p) container_of((p), struct nvkm_disp, client.object)
 #include <engine/disp.h>
 #include <core/enum.h>
 struct nvkm_head;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
index 2dab6612c4fc..5e44ec977d42 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c
@@ -154,9 +154,9 @@ nvkm_uconn_dtor(struct nvkm_object *object)
 	struct nvkm_conn *conn = nvkm_uconn(object);
 	struct nvkm_disp *disp = conn->disp;
 
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	conn->object.func = NULL;
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return NULL;
 }
 
@@ -166,10 +166,11 @@ nvkm_uconn = {
 	.uevent = nvkm_uconn_uevent,
 };
 
+#include "udisp.h"
 int
 nvkm_uconn_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 	struct nvkm_conn *cont, *conn = NULL;
 	union nvif_conn_args *args = argv;
 	int ret;
@@ -188,7 +189,7 @@ nvkm_uconn_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 		return -EINVAL;
 
 	ret = -EBUSY;
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	if (!conn->object.func) {
 		switch (conn->info.type) {
 		case DCB_CONNECTOR_VGA      : args->v0.type = NVIF_CONN_V0_VGA; break;
@@ -220,6 +221,6 @@ nvkm_uconn_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 		*pobject = &conn->object;
 		ret = 0;
 	}
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
index 0268d1d75805..272d6a040a51 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
@@ -19,7 +19,7 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-#include "priv.h"
+#include "udisp.h"
 #include "conn.h"
 #include "head.h"
 #include "outp.h"
@@ -30,7 +30,7 @@
 static int
 nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *sclass)
 {
-	struct nvkm_disp *disp = nvkm_udisp(object);
+	struct nvkm_disp *disp = container_of(object, struct nvif_disp_priv, object)->disp;
 
 	if (index-- == 0) {
 		sclass->base = (struct nvkm_sclass) { 0, 0, NVIF_CLASS_CONN };
@@ -62,13 +62,13 @@ nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *scl
 static void *
 nvkm_udisp_dtor(struct nvkm_object *object)
 {
-	struct nvkm_disp *disp = nvkm_udisp(object);
+	struct nvif_disp_priv *udisp = container_of(object, typeof(*udisp), object);
+	struct nvkm_disp *disp = udisp->disp;
 
-	spin_lock(&disp->client.lock);
-	if (object == &disp->client.object)
-		disp->client.object.func = NULL;
-	spin_unlock(&disp->client.lock);
-	return NULL;
+	spin_lock(&disp->user.lock);
+	disp->user.allocated = false;
+	spin_unlock(&disp->user.lock);
+	return udisp;
 }
 
 static const struct nvkm_object_func
@@ -85,18 +85,27 @@ nvkm_udisp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 	struct nvkm_outp *outp;
 	struct nvkm_head *head;
 	union nvif_disp_args *args = argv;
+	struct nvif_disp_priv *udisp;
 
 	if (argc != sizeof(args->v0) || args->v0.version != 0)
 		return -ENOSYS;
 
-	spin_lock(&disp->client.lock);
-	if (disp->client.object.func) {
-		spin_unlock(&disp->client.lock);
+	udisp = kzalloc(sizeof(*udisp), GFP_KERNEL);
+	if (!udisp)
+		return -ENOMEM;
+
+	spin_lock(&disp->user.lock);
+	if (disp->user.allocated) {
+		spin_unlock(&disp->user.lock);
+		kfree(udisp);
 		return -EBUSY;
 	}
-	nvkm_object_ctor(&nvkm_udisp, oclass, &disp->client.object);
-	*pobject = &disp->client.object;
-	spin_unlock(&disp->client.lock);
+	disp->user.allocated = true;
+	spin_unlock(&disp->user.lock);
+
+	nvkm_object_ctor(&nvkm_udisp, oclass, &udisp->object);
+	udisp->disp = disp;
+	*pobject = &udisp->object;
 
 	args->v0.conn_mask = 0;
 	list_for_each_entry(conn, &disp->conns, head)
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h
new file mode 100644
index 000000000000..2918ecbca5d3
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UDISP_H__
+#define __NVKM_UDISP_H__
+#include <core/object.h>
+#include "priv.h"
+
+struct nvif_disp_priv {
+	struct nvkm_object object;
+	struct nvkm_disp *disp;
+};
+#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
index f072cec16040..89e9b61914d6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uhead.c
@@ -89,9 +89,9 @@ nvkm_uhead_dtor(struct nvkm_object *object)
 	struct nvkm_head *head = nvkm_uhead(object);
 	struct nvkm_disp *disp = head->disp;
 
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	head->object.func = NULL;
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return NULL;
 }
 
@@ -102,10 +102,11 @@ nvkm_uhead = {
 	.uevent = nvkm_uhead_uevent,
 };
 
+#include "udisp.h"
 int
 nvkm_uhead_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 	struct nvkm_head *head;
 	union nvif_head_args *args = argv;
 	int ret;
@@ -116,12 +117,12 @@ nvkm_uhead_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 		return -EINVAL;
 
 	ret = -EBUSY;
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	if (!head->object.func) {
 		nvkm_object_ctor(&nvkm_uhead, oclass, &head->object);
 		*pobject = &head->object;
 		ret = 0;
 	}
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 377d0e0cef84..75669d5f8a42 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -570,9 +570,9 @@ nvkm_uoutp_dtor(struct nvkm_object *object)
 	struct nvkm_outp *outp = nvkm_uoutp(object);
 	struct nvkm_disp *disp = outp->disp;
 
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	outp->object.func = NULL;
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return NULL;
 }
 
@@ -582,10 +582,11 @@ nvkm_uoutp = {
 	.mthd = nvkm_uoutp_mthd,
 };
 
+#include "udisp.h"
 int
 nvkm_uoutp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_udisp(oclass->parent);
+	struct nvkm_disp *disp = container_of(oclass->parent, struct nvif_disp_priv, object)->disp;
 	struct nvkm_outp *outt, *outp = NULL;
 	union nvif_outp_args *args = argv;
 	int ret;
@@ -604,7 +605,7 @@ nvkm_uoutp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 		return -EINVAL;
 
 	ret = -EBUSY;
-	spin_lock(&disp->client.lock);
+	spin_lock(&disp->user.lock);
 	if (!outp->object.func) {
 		switch (outp->info.type) {
 		case DCB_OUTPUT_ANALOG:
@@ -660,6 +661,6 @@ nvkm_uoutp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nv
 	}
 
 done:
-	spin_unlock(&disp->client.lock);
+	spin_unlock(&disp->user.lock);
 	return ret;
 }
-- 
2.41.0



More information about the Nouveau mailing list