Commit 468fae7b authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/fifo: add cgrp, have all channels be part of one



Engine context tracking will move to nvkm_cgrp in later commits, so we
create SW-only channel groups on HW without support for them.

- switches to nvkm_chid for TSG/channel ID allocation

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent eb39c613
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@
#include <core/event.h>
struct nvkm_fault_data;

#define NVKM_FIFO_CHID_NR 4096
#define NVKM_FIFO_ENGN_NR 16

struct nvkm_fifo_engn {
@@ -17,13 +16,16 @@ struct nvkm_fifo_engn {

struct nvkm_chan {
	const struct nvkm_chan_func *func;
	char name[64];
	struct nvkm_cgrp *cgrp;

	union { int id; int chid; }; /*FIXME: remove later */

	struct nvkm_fifo *fifo;
	u32 engm;
	struct nvkm_object object;

	struct list_head head;
	u16 chid;
	struct nvkm_gpuobj *inst;
	struct nvkm_gpuobj *push;
	struct nvkm_vmm *vmm;
@@ -43,7 +45,6 @@ struct nvkm_fifo {
	struct list_head runqs;
	struct list_head runls;

	DECLARE_BITMAP(mask, NVKM_FIFO_CHID_NR);
	int nr;
	struct list_head chan;
	spinlock_t lock;
+1 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: MIT
nvkm-y += nvkm/engine/fifo/base.o
nvkm-y += nvkm/engine/fifo/cgrp.o
nvkm-y += nvkm/engine/fifo/chan.o
nvkm-y += nvkm/engine/fifo/chid.o
nvkm-y += nvkm/engine/fifo/runl.o
+1 −4
Original line number Diff line number Diff line
@@ -389,9 +389,6 @@ nvkm_fifo_ctor(const struct nvkm_fifo_func *func, struct nvkm_device *device,
	INIT_LIST_HEAD(&fifo->chan);

	nr = func->chid_nr(fifo);
	if (WARN_ON(fifo->nr > NVKM_FIFO_CHID_NR))
		fifo->nr = NVKM_FIFO_CHID_NR;
	else
	fifo->nr = nr;

	if (func->uevent_init) {
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
#include "cgrp.h"
#include "chan.h"
#include "chid.h"
#include "runl.h"
#include "priv.h"

#include <subdev/mmu.h>

static void
nvkm_cgrp_del(struct kref *kref)
{
	struct nvkm_cgrp *cgrp = container_of(kref, typeof(*cgrp), kref);
	struct nvkm_runl *runl = cgrp->runl;

	if (runl->cgid)
		nvkm_chid_put(runl->cgid, cgrp->id, &cgrp->lock);

	nvkm_vmm_unref(&cgrp->vmm);
	kfree(cgrp);
}

void
nvkm_cgrp_unref(struct nvkm_cgrp **pcgrp)
{
	struct nvkm_cgrp *cgrp = *pcgrp;

	if (!cgrp)
		return;

	kref_put(&cgrp->kref, nvkm_cgrp_del);
	*pcgrp = NULL;
}

struct nvkm_cgrp *
nvkm_cgrp_ref(struct nvkm_cgrp *cgrp)
{
	if (cgrp)
		kref_get(&cgrp->kref);

	return cgrp;
}

int
nvkm_cgrp_new(struct nvkm_runl *runl, const char *name, struct nvkm_vmm *vmm, bool hw,
	      struct nvkm_cgrp **pcgrp)
{
	struct nvkm_cgrp *cgrp;

	if (!(cgrp = *pcgrp = kmalloc(sizeof(*cgrp), GFP_KERNEL)))
		return -ENOMEM;

	cgrp->func = runl->fifo->func->cgrp.func;
	strscpy(cgrp->name, name, sizeof(cgrp->name));
	cgrp->runl = runl;
	cgrp->vmm = nvkm_vmm_ref(vmm);
	cgrp->hw = hw;
	cgrp->id = -1;
	kref_init(&cgrp->kref);
	cgrp->chans = NULL;
	cgrp->chan_nr = 0;
	spin_lock_init(&cgrp->lock);

	if (runl->cgid) {
		cgrp->id = nvkm_chid_get(runl->cgid, cgrp);
		if (cgrp->id < 0) {
			RUNL_ERROR(runl, "!cgids");
			nvkm_cgrp_unref(pcgrp);
			return -ENOSPC;
		}
	}

	return 0;
}
+22 −1
Original line number Diff line number Diff line
@@ -2,13 +2,34 @@
#ifndef __NVKM_CGRP_H__
#define __NVKM_CGRP_H__
#include <core/os.h>
struct nvkm_chan;

struct nvkm_cgrp {
	const struct nvkm_cgrp_func {
	} *func;
	char name[64];
	struct nvkm_runl *runl;
	struct nvkm_vmm *vmm;
	bool hw;
	int id;
	struct kref kref;

	struct nvkm_chan *chans;
	int chan_nr;

	spinlock_t lock; /* protects irq handler channel (group) lookup */

	struct list_head head;
	struct list_head chan;
	int chan_nr;
};

int nvkm_cgrp_new(struct nvkm_runl *, const char *name, struct nvkm_vmm *, bool hw,
		  struct nvkm_cgrp **);
struct nvkm_cgrp *nvkm_cgrp_ref(struct nvkm_cgrp *);
void nvkm_cgrp_unref(struct nvkm_cgrp **);

#define CGRP_PRCLI(c,l,p,f,a...) RUNL_PRINT((c)->runl, l, p, "%04x:[%s]"f, (c)->id, (c)->name, ##a)
#define CGRP_PRINT(c,l,p,f,a...) RUNL_PRINT((c)->runl, l, p, "%04x:"f, (c)->id, ##a)
#define CGRP_ERROR(c,f,a...) CGRP_PRCLI((c), ERROR,    err, " "f"\n", ##a)
#define CGRP_TRACE(c,f,a...) CGRP_PRINT((c), TRACE,   info, " "f"\n", ##a)
#endif
Loading