drm/nouveau/engine: use refcount_t + private mutex

nvkm_subdev.mutex is going away.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
This commit is contained in:
Ben Skeggs 2020-12-02 16:09:25 +10:00
parent 4c3a329273
commit 71ccf2a04e
2 changed files with 25 additions and 13 deletions

View file

@ -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 {

View file

@ -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);
return ERR_PTR(ret);
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");