From owner-svn-src-head@FreeBSD.ORG Sun Aug 25 14:47:23 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 45CF7414; Sun, 25 Aug 2013 14:47:23 +0000 (UTC) (envelope-from dumbbell@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 32A602146; Sun, 25 Aug 2013 14:47:23 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7PElNYd045174; Sun, 25 Aug 2013 14:47:23 GMT (envelope-from dumbbell@svn.freebsd.org) Received: (from dumbbell@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7PElMhR045172; Sun, 25 Aug 2013 14:47:22 GMT (envelope-from dumbbell@svn.freebsd.org) Message-Id: <201308251447.r7PElMhR045172@svn.freebsd.org> From: Jean-Sebastien Pedron Date: Sun, 25 Aug 2013 14:47:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254863 - head/sys/dev/drm2/ttm X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 25 Aug 2013 14:47:23 -0000 Author: dumbbell Date: Sun Aug 25 14:47:22 2013 New Revision: 254863 URL: http://svnweb.freebsd.org/changeset/base/254863 Log: drm/ttm: Import Linux commit 5e45d7dfd74100d622f9cdc70bfd1f9fae1671de Author: Maarten Lankhorst Date: Tue Jan 15 14:57:05 2013 +0100 drm/ttm: add ttm_bo_reserve_slowpath Instead of dropping everything, waiting for the bo to be unreserved and trying over, a better strategy would be to do a blocking wait. This can be mapped a lot better to a mutex_lock-like call. Signed-off-by: Maarten Lankhorst Reviewed-by: Jerome Glisse Approved by: kib@ Modified: head/sys/dev/drm2/ttm/ttm_bo.c head/sys/dev/drm2/ttm/ttm_bo_driver.h Modified: head/sys/dev/drm2/ttm/ttm_bo.c ============================================================================== --- head/sys/dev/drm2/ttm/ttm_bo.c Sun Aug 25 14:41:22 2013 (r254862) +++ head/sys/dev/drm2/ttm/ttm_bo.c Sun Aug 25 14:47:22 2013 (r254863) @@ -293,6 +293,56 @@ int ttm_bo_reserve(struct ttm_buffer_obj return ret; } +int ttm_bo_reserve_slowpath_nolru(struct ttm_buffer_object *bo, + bool interruptible, uint32_t sequence) +{ + bool wake_up = false; + int ret; + + while (unlikely(atomic_xchg(&bo->reserved, 1) != 0)) { + if (bo->seq_valid && sequence == bo->val_seq) { + DRM_ERROR( + "%s: bo->seq_valid && sequence == bo->val_seq", + __func__); + } + + ret = ttm_bo_wait_unreserved_locked(bo, interruptible); + + if (unlikely(ret)) + return ret; + } + + if ((bo->val_seq - sequence < (1 << 31)) || !bo->seq_valid) + wake_up = true; + + /** + * Wake up waiters that may need to recheck for deadlock, + * if we decreased the sequence number. + */ + bo->val_seq = sequence; + bo->seq_valid = true; + if (wake_up) + wakeup(bo); + + return 0; +} + +int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, + bool interruptible, uint32_t sequence) +{ + struct ttm_bo_global *glob = bo->glob; + int put_count, ret; + + ret = ttm_bo_reserve_slowpath_nolru(bo, interruptible, sequence); + if (likely(!ret)) { + mtx_lock(&glob->lru_lock); + put_count = ttm_bo_del_from_lru(bo); + mtx_unlock(&glob->lru_lock); + ttm_bo_list_ref_sub(bo, put_count, true); + } + return ret; +} + void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo) { ttm_bo_add_to_lru(bo); Modified: head/sys/dev/drm2/ttm/ttm_bo_driver.h ============================================================================== --- head/sys/dev/drm2/ttm/ttm_bo_driver.h Sun Aug 25 14:41:22 2013 (r254862) +++ head/sys/dev/drm2/ttm/ttm_bo_driver.h Sun Aug 25 14:47:22 2013 (r254863) @@ -822,6 +822,36 @@ extern int ttm_bo_reserve(struct ttm_buf bool interruptible, bool no_wait, bool use_sequence, uint32_t sequence); +/** + * 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, + uint32_t sequence); + + +/** + * ttm_bo_reserve_slowpath: + * @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. + */ +extern int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, + bool interruptible, uint32_t sequence); /** * ttm_bo_reserve_nolru: