From patchwork Thu Jun 27 11:48:24 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maarten Lankhorst X-Patchwork-Id: 2792171 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4AD00C0AB1 for ; Thu, 27 Jun 2013 12:02:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A107F201D3 for ; Thu, 27 Jun 2013 12:02:43 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D9F33201BC for ; Thu, 27 Jun 2013 12:02:41 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CF556E6473 for ; Thu, 27 Jun 2013 05:02:41 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-we0-f169.google.com (mail-we0-f169.google.com [74.125.82.169]) by gabe.freedesktop.org (Postfix) with ESMTP id 38BBDE5F3B for ; Thu, 27 Jun 2013 04:49:04 -0700 (PDT) Received: by mail-we0-f169.google.com with SMTP id n57so487395wev.0 for ; Thu, 27 Jun 2013 04:49:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=DMG5Xih9cE3YvBYBbqOf61LPpzQ+cUBYFFtNhZ7WxxA=; b=U+93zIvYJLr8buQaQi5xDRKg4nPF3dr7qHwxL320ROmoDrFLYKS+nkrx6jbo/ys/se rshAMIAOPV2n2VoIF/rq6E774KnP3eHk+l+z+yd38MacAnJForqFMScB4R+34D9/naMy 7gErccH4fszLzPJAnqOP+YPL28+NFmYlCCdM/Szno/MP9AXXAmYeXuWDbp9pUU3MxK56 uMjWpzCft450EZQ3M3bpYJtePrIrnxxDeEz7TwKpLinR0DaTidt0Wmxdyr4dFaQAlc7f 7OwPprchF7EUmOYVf/HjJ/0Fi3eGFDsV8ogFz0iBbXuP91T06EC+B3ACWDL5MwCpOSYY 3+wg== X-Received: by 10.180.83.68 with SMTP id o4mr2241176wiy.5.1372333743379; Thu, 27 Jun 2013 04:49:03 -0700 (PDT) Received: from localhost (5ED49945.cm-7-5c.dynamic.ziggo.nl. [94.212.153.69]) by mx.google.com with ESMTPSA id f8sm2627586wiv.0.2013.06.27.04.49.01 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 27 Jun 2013 04:49:02 -0700 (PDT) Received: by localhost (sSMTP sendmail emulation); Thu, 27 Jun 2013 13:49:01 +0200 From: Maarten Lankhorst To: Dave Airlie Subject: [PATCH WW 09/13] drm/ttm: inline ttm_bo_reserve and related calls Date: Thu, 27 Jun 2013 13:48:24 +0200 Message-Id: <1372333708-29884-10-git-send-email-maarten.lankhorst@canonical.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1372333708-29884-1-git-send-email-maarten.lankhorst@canonical.com> References: <1372333708-29884-1-git-send-email-maarten.lankhorst@canonical.com> Cc: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-5.4 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Makes lockdep a lot more useful. Signed-off-by: Maarten Lankhorst --- 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 ++++++++++++++++++++------------- 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 #include #include +#include #include #include #include @@ -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