Date: Sun, 25 Aug 2013 14:47:22 +0000 (UTC) From: Jean-Sebastien Pedron <dumbbell@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254863 - head/sys/dev/drm2/ttm Message-ID: <201308251447.r7PElMhR045172@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <maarten.lankhorst@canonical.com> 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 <maarten.lankhorst@canonical.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com> 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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201308251447.r7PElMhR045172>