static int submit_lock_objects(struct etnaviv_gem_submit *submit, struct ww_acquire_ctx *ticket) { int contended, slow_locked = -1, i, ret = 0; retry: for (i = 0; i < submit->nr_bos; i++) { struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj; if (slow_locked == i) slow_locked = -1; contended = i; if (!(submit->bos[i].flags & BO_LOCKED)) { ret = ww_mutex_lock_interruptible(&etnaviv_obj->resv->lock, ticket); if (ret == -EALREADY) DRM_ERROR("BO at index %u already on submit list\n", i); if (ret) goto fail; submit->bos[i].flags |= BO_LOCKED; } } ww_acquire_done(ticket); return 0; fail: for (; i >= 0; i--) submit_unlock_object(submit, i); if (slow_locked > 0) submit_unlock_object(submit, slow_locked); if (ret == -EDEADLK) { struct etnaviv_gem_object *etnaviv_obj; etnaviv_obj = submit->bos[contended].obj; /* we lost out in a seqno race, lock and retry.. */ ret = ww_mutex_lock_slow_interruptible(&etnaviv_obj->resv->lock, ticket); if (!ret) { submit->bos[contended].flags |= BO_LOCKED; slow_locked = contended; goto retry; } } return ret; }
static inline int modeset_lock(struct drm_modeset_lock *lock, struct drm_modeset_acquire_ctx *ctx, bool interruptible, bool slow) { int ret; WARN_ON(ctx->contended); if (ctx->trylock_only) { lockdep_assert_held(&ctx->ww_ctx); if (!ww_mutex_trylock(&lock->mutex)) return -EBUSY; else return 0; } else if (interruptible && slow) { ret = ww_mutex_lock_slow_interruptible(&lock->mutex, &ctx->ww_ctx); } else if (interruptible) { ret = ww_mutex_lock_interruptible(&lock->mutex, &ctx->ww_ctx); } else if (slow) { ww_mutex_lock_slow(&lock->mutex, &ctx->ww_ctx); ret = 0; } else { ret = ww_mutex_lock(&lock->mutex, &ctx->ww_ctx); } if (!ret) { WARN_ON(!list_empty(&lock->head)); list_add(&lock->head, &ctx->locked); } else if (ret == -EALREADY) { /* we already hold the lock.. this is fine. For atomic * we will need to be able to drm_modeset_lock() things * without having to keep track of what is already locked * or not. */ ret = 0; } else if (ret == -EDEADLK) { ctx->contended = lock; } return ret; }