LCOV - code coverage report
Current view: top level - dev/pci/drm/ttm - ttm_execbuf_util.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 92 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /**************************************************************************
       2             :  *
       3             :  * Copyright (c) 2006-2009 VMware, Inc., Palo Alto, CA., USA
       4             :  * All Rights Reserved.
       5             :  *
       6             :  * Permission is hereby granted, free of charge, to any person obtaining a
       7             :  * copy of this software and associated documentation files (the
       8             :  * "Software"), to deal in the Software without restriction, including
       9             :  * without limitation the rights to use, copy, modify, merge, publish,
      10             :  * distribute, sub license, and/or sell copies of the Software, and to
      11             :  * permit persons to whom the Software is furnished to do so, subject to
      12             :  * the following conditions:
      13             :  *
      14             :  * The above copyright notice and this permission notice (including the
      15             :  * next paragraph) shall be included in all copies or substantial portions
      16             :  * of the Software.
      17             :  *
      18             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20             :  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
      21             :  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
      22             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
      23             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
      24             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.
      25             :  *
      26             :  **************************************************************************/
      27             : 
      28             : #include <dev/pci/drm/ttm/ttm_execbuf_util.h>
      29             : #include <dev/pci/drm/ttm/ttm_bo_driver.h>
      30             : #include <dev/pci/drm/ttm/ttm_placement.h>
      31             : 
      32           0 : static void ttm_eu_backoff_reservation_reverse(struct list_head *list,
      33             :                                               struct ttm_validate_buffer *entry)
      34             : {
      35           0 :         list_for_each_entry_continue_reverse(entry, list, head) {
      36           0 :                 struct ttm_buffer_object *bo = entry->bo;
      37             : 
      38           0 :                 __ttm_bo_unreserve(bo);
      39             :         }
      40           0 : }
      41             : 
      42           0 : static void ttm_eu_del_from_lru_locked(struct list_head *list)
      43             : {
      44             :         struct ttm_validate_buffer *entry;
      45             : 
      46           0 :         list_for_each_entry(entry, list, head) {
      47           0 :                 struct ttm_buffer_object *bo = entry->bo;
      48           0 :                 unsigned put_count = ttm_bo_del_from_lru(bo);
      49             : 
      50           0 :                 ttm_bo_list_ref_sub(bo, put_count, true);
      51             :         }
      52           0 : }
      53             : 
      54           0 : void ttm_eu_backoff_reservation(struct ww_acquire_ctx *ticket,
      55             :                                 struct list_head *list)
      56             : {
      57             :         struct ttm_validate_buffer *entry;
      58             :         struct ttm_bo_global *glob;
      59             : 
      60           0 :         if (list_empty(list))
      61           0 :                 return;
      62             : 
      63           0 :         entry = list_first_entry(list, struct ttm_validate_buffer, head);
      64           0 :         glob = entry->bo->glob;
      65             : 
      66           0 :         spin_lock(&glob->lru_lock);
      67           0 :         list_for_each_entry(entry, list, head) {
      68           0 :                 struct ttm_buffer_object *bo = entry->bo;
      69             : 
      70           0 :                 ttm_bo_add_to_lru(bo);
      71           0 :                 __ttm_bo_unreserve(bo);
      72             :         }
      73           0 :         spin_unlock(&glob->lru_lock);
      74             : 
      75           0 :         if (ticket)
      76           0 :                 ww_acquire_fini(ticket);
      77           0 : }
      78             : EXPORT_SYMBOL(ttm_eu_backoff_reservation);
      79             : 
      80             : /*
      81             :  * Reserve buffers for validation.
      82             :  *
      83             :  * If a buffer in the list is marked for CPU access, we back off and
      84             :  * wait for that buffer to become free for GPU access.
      85             :  *
      86             :  * If a buffer is reserved for another validation, the validator with
      87             :  * the highest validation sequence backs off and waits for that buffer
      88             :  * to become unreserved. This prevents deadlocks when validating multiple
      89             :  * buffers in different orders.
      90             :  */
      91             : 
      92           0 : int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket,
      93             :                            struct list_head *list, bool intr,
      94             :                            struct list_head *dups)
      95             : {
      96             :         struct ttm_bo_global *glob;
      97             :         struct ttm_validate_buffer *entry;
      98             :         int ret;
      99             : 
     100           0 :         if (list_empty(list))
     101           0 :                 return 0;
     102             : 
     103           0 :         entry = list_first_entry(list, struct ttm_validate_buffer, head);
     104           0 :         glob = entry->bo->glob;
     105             : 
     106           0 :         if (ticket)
     107           0 :                 ww_acquire_init(ticket, &reservation_ww_class);
     108             : 
     109           0 :         list_for_each_entry(entry, list, head) {
     110           0 :                 struct ttm_buffer_object *bo = entry->bo;
     111             : 
     112           0 :                 ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), true,
     113             :                                        ticket);
     114           0 :                 if (!ret && unlikely(atomic_read(&bo->cpu_writers) > 0)) {
     115           0 :                         __ttm_bo_unreserve(bo);
     116             : 
     117             :                         ret = -EBUSY;
     118             : 
     119           0 :                 } else if (ret == -EALREADY && dups) {
     120             :                         struct ttm_validate_buffer *safe = entry;
     121           0 :                         entry = list_prev_entry(entry, head);
     122           0 :                         list_del(&safe->head);
     123           0 :                         list_add(&safe->head, dups);
     124             :                         continue;
     125             :                 }
     126             : 
     127           0 :                 if (!ret) {
     128           0 :                         if (!entry->shared)
     129           0 :                                 continue;
     130             : 
     131           0 :                         ret = reservation_object_reserve_shared(bo->resv);
     132           0 :                         if (!ret)
     133           0 :                                 continue;
     134             :                 }
     135             : 
     136             :                 /* uh oh, we lost out, drop every reservation and try
     137             :                  * to only reserve this buffer, then start over if
     138             :                  * this succeeds.
     139             :                  */
     140           0 :                 ttm_eu_backoff_reservation_reverse(list, entry);
     141             : 
     142           0 :                 if (ret == -EDEADLK && intr) {
     143           0 :                         ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
     144             :                                                                ticket);
     145           0 :                 } else if (ret == -EDEADLK) {
     146           0 :                         ww_mutex_lock_slow(&bo->resv->lock, ticket);
     147             :                         ret = 0;
     148           0 :                 }
     149             : 
     150           0 :                 if (!ret && entry->shared)
     151           0 :                         ret = reservation_object_reserve_shared(bo->resv);
     152             : 
     153           0 :                 if (unlikely(ret != 0)) {
     154           0 :                         if (ret == -EINTR)
     155           0 :                                 ret = -ERESTARTSYS;
     156           0 :                         if (ticket) {
     157           0 :                                 ww_acquire_done(ticket);
     158           0 :                                 ww_acquire_fini(ticket);
     159           0 :                         }
     160           0 :                         return ret;
     161             :                 }
     162             : 
     163             :                 /* move this item to the front of the list,
     164             :                  * forces correct iteration of the loop without keeping track
     165             :                  */
     166           0 :                 list_del(&entry->head);
     167           0 :                 list_add(&entry->head, list);
     168           0 :         }
     169             : 
     170           0 :         if (ticket)
     171           0 :                 ww_acquire_done(ticket);
     172           0 :         spin_lock(&glob->lru_lock);
     173           0 :         ttm_eu_del_from_lru_locked(list);
     174           0 :         spin_unlock(&glob->lru_lock);
     175           0 :         return 0;
     176           0 : }
     177             : EXPORT_SYMBOL(ttm_eu_reserve_buffers);
     178             : 
     179           0 : void ttm_eu_fence_buffer_objects(struct ww_acquire_ctx *ticket,
     180             :                                  struct list_head *list, struct fence *fence)
     181             : {
     182             :         struct ttm_validate_buffer *entry;
     183             :         struct ttm_buffer_object *bo;
     184             :         struct ttm_bo_global *glob;
     185             :         struct ttm_bo_device *bdev;
     186             :         struct ttm_bo_driver *driver;
     187             : 
     188           0 :         if (list_empty(list))
     189           0 :                 return;
     190             : 
     191           0 :         bo = list_first_entry(list, struct ttm_validate_buffer, head)->bo;
     192           0 :         bdev = bo->bdev;
     193           0 :         driver = bdev->driver;
     194           0 :         glob = bo->glob;
     195             : 
     196           0 :         spin_lock(&glob->lru_lock);
     197             : 
     198           0 :         list_for_each_entry(entry, list, head) {
     199           0 :                 bo = entry->bo;
     200           0 :                 if (entry->shared)
     201           0 :                         reservation_object_add_shared_fence(bo->resv, fence);
     202             :                 else
     203           0 :                         reservation_object_add_excl_fence(bo->resv, fence);
     204           0 :                 ttm_bo_add_to_lru(bo);
     205           0 :                 __ttm_bo_unreserve(bo);
     206             :         }
     207           0 :         spin_unlock(&glob->lru_lock);
     208           0 :         if (ticket)
     209           0 :                 ww_acquire_fini(ticket);
     210           0 : }
     211             : EXPORT_SYMBOL(ttm_eu_fence_buffer_objects);

Generated by: LCOV version 1.13