Commit 71ccf2a0 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/engine: use refcount_t + private mutex



nvkm_subdev.mutex is going away.

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 4c3a3292
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -11,7 +11,11 @@ struct nvkm_engine {
	struct nvkm_subdev subdev;
	spinlock_t lock;

	int usecount;
	struct {
		refcount_t refcount;
		struct mutex mutex;
		bool enabled;
	} use;
};

struct nvkm_engine_func {
+20 −12
Original line number Diff line number Diff line
@@ -40,10 +40,11 @@ nvkm_engine_unref(struct nvkm_engine **pengine)
{
	struct nvkm_engine *engine = *pengine;
	if (engine) {
		mutex_lock(&engine->subdev.mutex);
		if (--engine->usecount == 0)
		if (refcount_dec_and_mutex_lock(&engine->use.refcount, &engine->use.mutex)) {
			nvkm_subdev_fini(&engine->subdev, false);
		mutex_unlock(&engine->subdev.mutex);
			engine->use.enabled = false;
			mutex_unlock(&engine->use.mutex);
		}
		*pengine = NULL;
	}
}
@@ -51,17 +52,21 @@ nvkm_engine_unref(struct nvkm_engine **pengine)
struct nvkm_engine *
nvkm_engine_ref(struct nvkm_engine *engine)
{
	int ret;
	if (engine) {
		mutex_lock(&engine->subdev.mutex);
		if (++engine->usecount == 1) {
			int ret = nvkm_subdev_init(&engine->subdev);
			if (ret) {
				engine->usecount--;
				mutex_unlock(&engine->subdev.mutex);
		if (!refcount_inc_not_zero(&engine->use.refcount)) {
			mutex_lock(&engine->use.mutex);
			if (!refcount_inc_not_zero(&engine->use.refcount)) {
				engine->use.enabled = true;
				if ((ret = nvkm_subdev_init(&engine->subdev))) {
					engine->use.enabled = false;
					mutex_unlock(&engine->use.mutex);
					return ERR_PTR(ret);
				}
				refcount_set(&engine->use.refcount, 1);
			}
			mutex_unlock(&engine->use.mutex);
		}
		mutex_unlock(&engine->subdev.mutex);
	}
	return engine;
}
@@ -114,7 +119,7 @@ nvkm_engine_init(struct nvkm_subdev *subdev)
	int ret = 0, i;
	s64 time;

	if (!engine->usecount) {
	if (!engine->use.enabled) {
		nvkm_trace(subdev, "init skipped, engine has no users\n");
		return ret;
	}
@@ -156,6 +161,7 @@ nvkm_engine_dtor(struct nvkm_subdev *subdev)
	struct nvkm_engine *engine = nvkm_engine(subdev);
	if (engine->func->dtor)
		return engine->func->dtor(engine);
	mutex_destroy(&engine->use.mutex);
	return engine;
}

@@ -176,6 +182,8 @@ nvkm_engine_ctor(const struct nvkm_engine_func *func,
{
	nvkm_subdev_ctor(&nvkm_engine_func, device, index, &engine->subdev);
	engine->func = func;
	refcount_set(&engine->use.refcount, 0);
	mutex_init(&engine->use.mutex);

	if (!nvkm_boolopt(device->cfgopt, nvkm_subdev_name[index], enable)) {
		nvkm_debug(&engine->subdev, "disabled\n");