From: Daniel Vetter <daniel@ffwll.ch>
To: Maarten Lankhorst <m.b.lankhorst@gmail.com>
Cc: Dave Airlie <airlied@redhat.com>, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH WW 09/13] drm/ttm: inline ttm_bo_reserve and related calls
Date: Thu, 27 Jun 2013 14:21:46 +0200 [thread overview]
Message-ID: <20130627122146.GP18285@phenom.ffwll.local> (raw)
In-Reply-To: <1372333708-29884-10-git-send-email-maarten.lankhorst@canonical.com>
On Thu, Jun 27, 2013 at 01:48:24PM +0200, Maarten Lankhorst wrote:
> Makes lockdep a lot more useful.
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
> ---
> drivers/gpu/drm/ttm/ttm_bo.c | 105 ++------------------
> drivers/gpu/drm/ttm/ttm_execbuf_util.c | 9 +-
> include/drm/ttm/ttm_bo_driver.h | 175 ++++++++++++++++++++-------------
The function movement in the header makes the diff a bit hard to read. So
if possible I think that should be avoided. Anyway I think I've spotted a
few kerneldoc updates (like s/EAGAIN/EDEADLK/) which should be part of the
main conversion patch.
-Daniel
> 3 files changed, 117 insertions(+), 172 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index 5f9fe80..a8a27f5 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -182,6 +182,7 @@ void ttm_bo_add_to_lru(struct ttm_buffer_object *bo)
> }
> }
> }
> +EXPORT_SYMBOL(ttm_bo_add_to_lru);
>
> int ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
> {
> @@ -204,35 +205,6 @@ int ttm_bo_del_from_lru(struct ttm_buffer_object *bo)
> return put_count;
> }
>
> -int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
> - bool interruptible,
> - bool no_wait, bool use_ticket,
> - struct ww_acquire_ctx *ticket)
> -{
> - int ret = 0;
> -
> - if (no_wait) {
> - bool success;
> -
> - /* not valid any more, fix your locking! */
> - if (WARN_ON(ticket))
> - return -EBUSY;
> -
> - success = ww_mutex_trylock(&bo->resv->lock);
> - return success ? 0 : -EBUSY;
> - }
> -
> - if (interruptible)
> - ret = ww_mutex_lock_interruptible(&bo->resv->lock,
> - ticket);
> - else
> - ret = ww_mutex_lock(&bo->resv->lock, ticket);
> - if (ret == -EINTR)
> - return -ERESTARTSYS;
> - return ret;
> -}
> -EXPORT_SYMBOL(ttm_bo_reserve);
> -
> static void ttm_bo_ref_bug(struct kref *list_kref)
> {
> BUG();
> @@ -245,77 +217,16 @@ void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count,
> (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list);
> }
>
> -int ttm_bo_reserve(struct ttm_buffer_object *bo,
> - bool interruptible,
> - bool no_wait, bool use_ticket,
> - struct ww_acquire_ctx *ticket)
> -{
> - struct ttm_bo_global *glob = bo->glob;
> - int put_count = 0;
> - int ret;
> -
> - ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_ticket,
> - ticket);
> - if (likely(ret == 0)) {
> - spin_lock(&glob->lru_lock);
> - put_count = ttm_bo_del_from_lru(bo);
> - spin_unlock(&glob->lru_lock);
> - ttm_bo_list_ref_sub(bo, put_count, true);
> - }
> -
> - return ret;
> -}
> -
> -int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
> - bool interruptible, struct ww_acquire_ctx *ticket)
> -{
> - struct ttm_bo_global *glob = bo->glob;
> - int put_count = 0;
> - int ret = 0;
> -
> - if (interruptible)
> - ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
> - ticket);
> - else
> - ww_mutex_lock_slow(&bo->resv->lock, ticket);
> -
> - if (likely(ret == 0)) {
> - spin_lock(&glob->lru_lock);
> - put_count = ttm_bo_del_from_lru(bo);
> - spin_unlock(&glob->lru_lock);
> - ttm_bo_list_ref_sub(bo, put_count, true);
> - } else if (ret == -EINTR)
> - ret = -ERESTARTSYS;
> -
> - return ret;
> -}
> -EXPORT_SYMBOL(ttm_bo_reserve_slowpath);
> -
> -void ttm_bo_unreserve_ticket_locked(struct ttm_buffer_object *bo, struct ww_acquire_ctx *ticket)
> +void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo)
> {
> - ttm_bo_add_to_lru(bo);
> - ww_mutex_unlock(&bo->resv->lock);
> -}
> -
> -void ttm_bo_unreserve(struct ttm_buffer_object *bo)
> -{
> - struct ttm_bo_global *glob = bo->glob;
> -
> - spin_lock(&glob->lru_lock);
> - ttm_bo_unreserve_ticket_locked(bo, NULL);
> - spin_unlock(&glob->lru_lock);
> -}
> -EXPORT_SYMBOL(ttm_bo_unreserve);
> -
> -void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo, struct ww_acquire_ctx *ticket)
> -{
> - struct ttm_bo_global *glob = bo->glob;
> + int put_count;
>
> - spin_lock(&glob->lru_lock);
> - ttm_bo_unreserve_ticket_locked(bo, ticket);
> - spin_unlock(&glob->lru_lock);
> + spin_lock(&bo->glob->lru_lock);
> + put_count = ttm_bo_del_from_lru(bo);
> + spin_unlock(&bo->glob->lru_lock);
> + ttm_bo_list_ref_sub(bo, put_count, true);
> }
> -EXPORT_SYMBOL(ttm_bo_unreserve_ticket);
> +EXPORT_SYMBOL(ttm_bo_del_sub_from_lru);
>
> /*
> * Call bo->mutex locked.
> diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
> index 7392da5..6c91178 100644
> --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c
> +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c
> @@ -44,12 +44,10 @@ static void ttm_eu_backoff_reservation_locked(struct list_head *list,
>
> entry->reserved = false;
> if (entry->removed) {
> - ttm_bo_unreserve_ticket_locked(bo, ticket);
> + ttm_bo_add_to_lru(bo);
> entry->removed = false;
> -
> - } else {
> - ww_mutex_unlock(&bo->resv->lock);
> }
> + ww_mutex_unlock(&bo->resv->lock);
> }
> }
>
> @@ -220,7 +218,8 @@ void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
> bo = entry->bo;
> entry->old_sync_obj = bo->sync_obj;
> bo->sync_obj = driver->sync_obj_ref(sync_obj);
> - ttm_bo_unreserve_ticket_locked(bo, ticket);
> + ttm_bo_add_to_lru(bo);
> + ww_mutex_unlock(&bo->resv->lock);
> entry->reserved = false;
> }
> spin_unlock(&bdev->fence_lock);
> diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
> index ec18c5f..984fc2d 100644
> --- a/include/drm/ttm/ttm_bo_driver.h
> +++ b/include/drm/ttm/ttm_bo_driver.h
> @@ -33,6 +33,7 @@
> #include <ttm/ttm_bo_api.h>
> #include <ttm/ttm_memory.h>
> #include <ttm/ttm_module.h>
> +#include <ttm/ttm_placement.h>
> #include <drm/drm_mm.h>
> #include <drm/drm_global.h>
> #include <linux/workqueue.h>
> @@ -772,6 +773,55 @@ extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man,
> bool interruptible);
> extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
>
> +extern void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo);
> +extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo);
> +
> +/**
> + * ttm_bo_reserve_nolru:
> + *
> + * @bo: A pointer to a struct ttm_buffer_object.
> + * @interruptible: Sleep interruptible if waiting.
> + * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
> + * @use_ticket: If @bo is already reserved, Only sleep waiting for
> + * it to become unreserved if @ticket->stamp is older.
> + *
> + * Will not remove reserved buffers from the lru lists.
> + * Otherwise identical to ttm_bo_reserve.
> + *
> + * Returns:
> + * -EDEADLK: The reservation may cause a deadlock.
> + * Release all buffer reservations, wait for @bo to become unreserved and
> + * try again. (only if use_sequence == 1).
> + * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
> + * a signal. Release all buffer reservations and return to user-space.
> + * -EBUSY: The function needed to sleep, but @no_wait was true
> + * -EALREADY: Bo already reserved using @ticket. This error code will only
> + * be returned if @use_ticket is set to true.
> + */
> +static inline int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
> + bool interruptible,
> + bool no_wait, bool use_ticket,
> + struct ww_acquire_ctx *ticket)
> +{
> + int ret = 0;
> +
> + if (no_wait) {
> + bool success;
> + if (WARN_ON(ticket))
> + return -EBUSY;
> +
> + success = ww_mutex_trylock(&bo->resv->lock);
> + return success ? 0 : -EBUSY;
> + }
> +
> + if (interruptible)
> + ret = ww_mutex_lock_interruptible(&bo->resv->lock, ticket);
> + else
> + ret = ww_mutex_lock(&bo->resv->lock, ticket);
> + if (ret == -EINTR)
> + return -ERESTARTSYS;
> + return ret;
> +}
>
> /**
> * ttm_bo_reserve:
> @@ -780,7 +830,7 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
> * @interruptible: Sleep interruptible if waiting.
> * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
> * @use_ticket: If @bo is already reserved, Only sleep waiting for
> - * it to become unreserved if @sequence < (@bo)->sequence.
> + * it to become unreserved if @ticket->stamp is older.
> *
> * Locks a buffer object for validation. (Or prevents other processes from
> * locking it for validation) and removes it from lru lists, while taking
> @@ -794,7 +844,7 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
> * Processes attempting to reserve multiple buffers other than for eviction,
> * (typically execbuf), should first obtain a unique 32-bit
> * validation sequence number,
> - * and call this function with @use_sequence == 1 and @sequence == the unique
> + * and call this function with @use_ticket == 1 and @ticket->stamp == the unique
> * sequence number. If upon call of this function, the buffer object is already
> * reserved, the validation sequence is checked against the validation
> * sequence of the process currently reserving the buffer,
> @@ -809,37 +859,31 @@ extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man);
> * will eventually succeed, preventing both deadlocks and starvation.
> *
> * Returns:
> - * -EAGAIN: The reservation may cause a deadlock.
> + * -EDEADLK: The reservation may cause a deadlock.
> * Release all buffer reservations, wait for @bo to become unreserved and
> * try again. (only if use_sequence == 1).
> * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
> * a signal. Release all buffer reservations and return to user-space.
> * -EBUSY: The function needed to sleep, but @no_wait was true
> - * -EDEADLK: Bo already reserved using @sequence. This error code will only
> - * be returned if @use_sequence is set to true.
> + * -EALREADY: Bo already reserved using @ticket. This error code will only
> + * be returned if @use_ticket is set to true.
> */
> -extern int ttm_bo_reserve(struct ttm_buffer_object *bo,
> - bool interruptible,
> - bool no_wait, bool use_ticket,
> - struct ww_acquire_ctx *ticket);
> +static inline int ttm_bo_reserve(struct ttm_buffer_object *bo,
> + bool interruptible,
> + bool no_wait, bool use_ticket,
> + struct ww_acquire_ctx *ticket)
> +{
> + int ret;
>
> -/**
> - * ttm_bo_reserve_slowpath_nolru:
> - * @bo: A pointer to a struct ttm_buffer_object.
> - * @interruptible: Sleep interruptible if waiting.
> - * @sequence: Set (@bo)->sequence to this value after lock
> - *
> - * This is called after ttm_bo_reserve returns -EAGAIN and we backed off
> - * from all our other reservations. Because there are no other reservations
> - * held by us, this function cannot deadlock any more.
> - *
> - * Will not remove reserved buffers from the lru lists.
> - * Otherwise identical to ttm_bo_reserve_slowpath.
> - */
> -extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
> - bool interruptible,
> - struct ww_acquire_ctx *ticket);
> + WARN_ON(!atomic_read(&bo->kref.refcount));
> +
> + ret = ttm_bo_reserve_nolru(bo, interruptible, no_wait, use_ticket,
> + ticket);
> + if (likely(ret == 0))
> + ttm_bo_del_sub_from_lru(bo);
>
> + return ret;
> +}
>
> /**
> * ttm_bo_reserve_slowpath:
> @@ -851,45 +895,27 @@ extern int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo,
> * from all our other reservations. Because there are no other reservations
> * held by us, this function cannot deadlock any more.
> */
> -extern int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
> - bool interruptible,
> - struct ww_acquire_ctx *ticket);
> +static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo,
> + bool interruptible,
> + struct ww_acquire_ctx *ticket)
> +{
> + int ret = 0;
>
> -/**
> - * ttm_bo_reserve_nolru:
> - *
> - * @bo: A pointer to a struct ttm_buffer_object.
> - * @interruptible: Sleep interruptible if waiting.
> - * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY.
> - * @use_sequence: If @bo is already reserved, Only sleep waiting for
> - * it to become unreserved if @sequence < (@bo)->sequence.
> - *
> - * Will not remove reserved buffers from the lru lists.
> - * Otherwise identical to ttm_bo_reserve.
> - *
> - * Returns:
> - * -EAGAIN: The reservation may cause a deadlock.
> - * Release all buffer reservations, wait for @bo to become unreserved and
> - * try again. (only if use_sequence == 1).
> - * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
> - * a signal. Release all buffer reservations and return to user-space.
> - * -EBUSY: The function needed to sleep, but @no_wait was true
> - * -EDEADLK: Bo already reserved using @sequence. This error code will only
> - * be returned if @use_sequence is set to true.
> - */
> -extern int ttm_bo_reserve_nolru(struct ttm_buffer_object *bo,
> - bool interruptible,
> - bool no_wait, bool use_ticket,
> - struct ww_acquire_ctx *ticket);
> + WARN_ON(!atomic_read(&bo->kref.refcount));
>
> -/**
> - * ttm_bo_unreserve
> - *
> - * @bo: A pointer to a struct ttm_buffer_object.
> - *
> - * Unreserve a previous reservation of @bo.
> - */
> -extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
> + if (interruptible)
> + ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
> + ticket);
> + else
> + ww_mutex_lock_slow(&bo->resv->lock, ticket);
> +
> + if (likely(ret == 0))
> + ttm_bo_del_sub_from_lru(bo);
> + else if (ret == -EINTR)
> + ret = -ERESTARTSYS;
> +
> + return ret;
> +}
>
> /**
> * ttm_bo_unreserve_ticket
> @@ -898,19 +924,28 @@ extern void ttm_bo_unreserve(struct ttm_buffer_object *bo);
> *
> * Unreserve a previous reservation of @bo made with @ticket.
> */
> -extern void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
> - struct ww_acquire_ctx *ticket);
> +static inline void ttm_bo_unreserve_ticket(struct ttm_buffer_object *bo,
> + struct ww_acquire_ctx *t)
> +{
> + if (!(bo->mem.placement & TTM_PL_FLAG_NO_EVICT)) {
> + spin_lock(&bo->glob->lru_lock);
> + ttm_bo_add_to_lru(bo);
> + spin_unlock(&bo->glob->lru_lock);
> + }
> + ww_mutex_unlock(&bo->resv->lock);
> +}
>
> /**
> - * ttm_bo_unreserve_locked
> + * ttm_bo_unreserve
> + *
> * @bo: A pointer to a struct ttm_buffer_object.
> - * @ticket: ww_acquire_ctx used for reserving, or NULL
> *
> - * Unreserve a previous reservation of @bo made with @ticket.
> - * Needs to be called with struct ttm_bo_global::lru_lock held.
> + * Unreserve a previous reservation of @bo.
> */
> -extern void ttm_bo_unreserve_ticket_locked(struct ttm_buffer_object *bo,
> - struct ww_acquire_ctx *ticket);
> +static inline void ttm_bo_unreserve(struct ttm_buffer_object *bo)
> +{
> + ttm_bo_unreserve_ticket(bo, NULL);
> +}
>
> /*
> * ttm_bo_util.c
> --
> 1.8.3.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
next prev parent reply other threads:[~2013-06-27 12:21 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-27 11:48 [PATCH WW 00/13] Convert TTM to Wound/wait mutexes Maarten Lankhorst
2013-06-27 11:48 ` [PATCH WW 01/13] reservation: cross-device reservation support, v4 Maarten Lankhorst
2013-06-27 21:45 ` Jerome Glisse
2013-06-27 11:48 ` [PATCH WW 02/13] drm/ttm: make ttm reservation calls behave like reservation calls Maarten Lankhorst
2013-06-27 21:47 ` Jerome Glisse
2013-06-27 11:48 ` [PATCH WW 03/13] drm/nouveau: make flipping lockdep safe Maarten Lankhorst
2013-06-27 11:48 ` [PATCH WW 04/13] drm/ttm: convert to the reservation api Maarten Lankhorst
2013-06-27 22:03 ` Jerome Glisse
2013-06-27 11:48 ` [PATCH WW 05/13] drm/ast: inline reservations Maarten Lankhorst
2013-06-27 11:48 ` [PATCH WW 06/13] drm/cirrus: " Maarten Lankhorst
2013-06-27 11:48 ` [PATCH WW 07/13] drm/mgag200: " Maarten Lankhorst
2013-06-27 11:48 ` [PATCH WW 08/13] drm/radeon: " Maarten Lankhorst
2013-06-27 22:04 ` Jerome Glisse
2013-06-27 11:48 ` [PATCH WW 09/13] drm/ttm: inline ttm_bo_reserve and related calls Maarten Lankhorst
2013-06-27 12:21 ` Daniel Vetter [this message]
2013-06-27 11:48 ` [PATCH WW 10/13] drm/ttm: get rid of ttm_bo_is_reserved usage Maarten Lankhorst
2013-06-27 12:23 ` Daniel Vetter
2013-06-27 11:48 ` [PATCH WW 11/13] drm/radeon: " Maarten Lankhorst
2013-06-27 22:05 ` Jerome Glisse
2013-06-27 11:48 ` [PATCH WW 12/13] drm/vmwgfx: " Maarten Lankhorst
2013-06-27 11:48 ` [PATCH WW 13/13] drm/ttm: get rid of ttm_bo_is_reserved Maarten Lankhorst
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130627122146.GP18285@phenom.ffwll.local \
--to=daniel@ffwll.ch \
--cc=airlied@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=m.b.lankhorst@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.