Loading drivers/gpu/drm/ttm/ttm_bo.c +8 −97 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); Loading @@ -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) void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) { 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); int put_count; if (likely(ret == 0)) { spin_lock(&glob->lru_lock); spin_lock(&bo->glob->lru_lock); put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); spin_unlock(&bo->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) { 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; spin_lock(&glob->lru_lock); ttm_bo_unreserve_ticket_locked(bo, ticket); spin_unlock(&glob->lru_lock); } EXPORT_SYMBOL(ttm_bo_unreserve_ticket); EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); /* * Call bo->mutex locked. Loading drivers/gpu/drm/ttm/ttm_execbuf_util.c +4 −5 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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); Loading include/drm/ttm/ttm_bo_driver.h +105 −70 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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: Loading @@ -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 Loading @@ -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, Loading @@ -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, static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, bool interruptible, bool no_wait, bool use_ticket, struct ww_acquire_ctx *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: Loading @@ -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, static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, bool interruptible, struct ww_acquire_ctx *ticket); 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 Loading @@ -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 Loading Loading
drivers/gpu/drm/ttm/ttm_bo.c +8 −97 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); Loading @@ -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) void ttm_bo_del_sub_from_lru(struct ttm_buffer_object *bo) { 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); int put_count; if (likely(ret == 0)) { spin_lock(&glob->lru_lock); spin_lock(&bo->glob->lru_lock); put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); spin_unlock(&bo->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) { 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; spin_lock(&glob->lru_lock); ttm_bo_unreserve_ticket_locked(bo, ticket); spin_unlock(&glob->lru_lock); } EXPORT_SYMBOL(ttm_bo_unreserve_ticket); EXPORT_SYMBOL(ttm_bo_del_sub_from_lru); /* * Call bo->mutex locked. Loading
drivers/gpu/drm/ttm/ttm_execbuf_util.c +4 −5 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading @@ -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); Loading
include/drm/ttm/ttm_bo_driver.h +105 −70 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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: Loading @@ -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 Loading @@ -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, Loading @@ -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, static inline int ttm_bo_reserve(struct ttm_buffer_object *bo, bool interruptible, bool no_wait, bool use_ticket, struct ww_acquire_ctx *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: Loading @@ -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, static inline int ttm_bo_reserve_slowpath(struct ttm_buffer_object *bo, bool interruptible, struct ww_acquire_ctx *ticket); 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 Loading @@ -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 Loading