LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - radeon_sync.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 78 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             :  * Copyright 2014 Advanced Micro Devices, Inc.
       3             :  * All Rights Reserved.
       4             :  *
       5             :  * Permission is hereby granted, free of charge, to any person obtaining a
       6             :  * copy of this software and associated documentation files (the
       7             :  * "Software"), to deal in the Software without restriction, including
       8             :  * without limitation the rights to use, copy, modify, merge, publish,
       9             :  * distribute, sub license, and/or sell copies of the Software, and to
      10             :  * permit persons to whom the Software is furnished to do so, subject to
      11             :  * the following conditions:
      12             :  *
      13             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      14             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      15             :  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
      16             :  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
      17             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
      18             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
      19             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.
      20             :  *
      21             :  * The above copyright notice and this permission notice (including the
      22             :  * next paragraph) shall be included in all copies or substantial portions
      23             :  * of the Software.
      24             :  *
      25             :  */
      26             : /*
      27             :  * Authors:
      28             :  *    Christian König <christian.koenig@amd.com>
      29             :  */
      30             : 
      31             : #include <dev/pci/drm/drmP.h>
      32             : #include "radeon.h"
      33             : #include "radeon_trace.h"
      34             : 
      35             : /**
      36             :  * radeon_sync_create - zero init sync object
      37             :  *
      38             :  * @sync: sync object to initialize
      39             :  *
      40             :  * Just clear the sync object for now.
      41             :  */
      42           0 : void radeon_sync_create(struct radeon_sync *sync)
      43             : {
      44             :         unsigned i;
      45             : 
      46           0 :         for (i = 0; i < RADEON_NUM_SYNCS; ++i)
      47           0 :                 sync->semaphores[i] = NULL;
      48             : 
      49           0 :         for (i = 0; i < RADEON_NUM_RINGS; ++i)
      50           0 :                 sync->sync_to[i] = NULL;
      51             : 
      52           0 :         sync->last_vm_update = NULL;
      53           0 : }
      54             : 
      55             : /**
      56             :  * radeon_sync_fence - use the semaphore to sync to a fence
      57             :  *
      58             :  * @sync: sync object to add fence to
      59             :  * @fence: fence to sync to
      60             :  *
      61             :  * Sync to the fence using the semaphore objects
      62             :  */
      63           0 : void radeon_sync_fence(struct radeon_sync *sync,
      64             :                        struct radeon_fence *fence)
      65             : {
      66             :         struct radeon_fence *other;
      67             : 
      68           0 :         if (!fence)
      69           0 :                 return;
      70             : 
      71           0 :         other = sync->sync_to[fence->ring];
      72           0 :         sync->sync_to[fence->ring] = radeon_fence_later(fence, other);
      73             : 
      74           0 :         if (fence->is_vm_update) {
      75           0 :                 other = sync->last_vm_update;
      76           0 :                 sync->last_vm_update = radeon_fence_later(fence, other);
      77           0 :         }
      78           0 : }
      79             : 
      80             : /**
      81             :  * radeon_sync_resv - use the semaphores to sync to a reservation object
      82             :  *
      83             :  * @sync: sync object to add fences from reservation object to
      84             :  * @resv: reservation object with embedded fence
      85             :  * @shared: true if we should only sync to the exclusive fence
      86             :  *
      87             :  * Sync to the fence using the semaphore objects
      88             :  */
      89           0 : int radeon_sync_resv(struct radeon_device *rdev,
      90             :                      struct radeon_sync *sync,
      91             :                      struct reservation_object *resv,
      92             :                      bool shared)
      93             : {
      94             :         struct reservation_object_list *flist;
      95             :         struct fence *f;
      96             :         struct radeon_fence *fence;
      97             :         unsigned i;
      98             :         int r = 0;
      99             : 
     100             :         /* always sync to the exclusive fence */
     101           0 :         f = reservation_object_get_excl(resv);
     102           0 :         fence = f ? to_radeon_fence(f) : NULL;
     103           0 :         if (fence && fence->rdev == rdev)
     104           0 :                 radeon_sync_fence(sync, fence);
     105           0 :         else if (f)
     106           0 :                 r = fence_wait(f, true);
     107             : 
     108           0 :         flist = reservation_object_get_list(resv);
     109           0 :         if (shared || !flist || r)
     110           0 :                 return r;
     111             : 
     112           0 :         for (i = 0; i < flist->shared_count; ++i) {
     113           0 :                 f = rcu_dereference_protected(flist->shared[i],
     114             :                                               reservation_object_held(resv));
     115           0 :                 fence = to_radeon_fence(f);
     116           0 :                 if (fence && fence->rdev == rdev)
     117           0 :                         radeon_sync_fence(sync, fence);
     118             :                 else
     119           0 :                         r = fence_wait(f, true);
     120             : 
     121           0 :                 if (r)
     122             :                         break;
     123             :         }
     124           0 :         return r;
     125           0 : }
     126             : 
     127             : /**
     128             :  * radeon_sync_rings - sync ring to all registered fences
     129             :  *
     130             :  * @rdev: radeon_device pointer
     131             :  * @sync: sync object to use
     132             :  * @ring: ring that needs sync
     133             :  *
     134             :  * Ensure that all registered fences are signaled before letting
     135             :  * the ring continue. The caller must hold the ring lock.
     136             :  */
     137           0 : int radeon_sync_rings(struct radeon_device *rdev,
     138             :                       struct radeon_sync *sync,
     139             :                       int ring)
     140             : {
     141             :         unsigned count = 0;
     142             :         int i, r;
     143             : 
     144           0 :         for (i = 0; i < RADEON_NUM_RINGS; ++i) {
     145           0 :                 struct radeon_fence *fence = sync->sync_to[i];
     146           0 :                 struct radeon_semaphore *semaphore;
     147             : 
     148             :                 /* check if we really need to sync */
     149           0 :                 if (!radeon_fence_need_sync(fence, ring))
     150           0 :                         continue;
     151             : 
     152             :                 /* prevent GPU deadlocks */
     153           0 :                 if (!rdev->ring[i].ready) {
     154           0 :                         dev_err(rdev->dev, "Syncing to a disabled ring!");
     155           0 :                         return -EINVAL;
     156             :                 }
     157             : 
     158           0 :                 if (count >= RADEON_NUM_SYNCS) {
     159             :                         /* not enough room, wait manually */
     160           0 :                         r = radeon_fence_wait(fence, false);
     161           0 :                         if (r)
     162           0 :                                 return r;
     163           0 :                         continue;
     164             :                 }
     165           0 :                 r = radeon_semaphore_create(rdev, &semaphore);
     166           0 :                 if (r)
     167           0 :                         return r;
     168             : 
     169           0 :                 sync->semaphores[count++] = semaphore;
     170             : 
     171             :                 /* allocate enough space for sync command */
     172           0 :                 r = radeon_ring_alloc(rdev, &rdev->ring[i], 16);
     173           0 :                 if (r)
     174           0 :                         return r;
     175             : 
     176             :                 /* emit the signal semaphore */
     177           0 :                 if (!radeon_semaphore_emit_signal(rdev, i, semaphore)) {
     178             :                         /* signaling wasn't successful wait manually */
     179           0 :                         radeon_ring_undo(&rdev->ring[i]);
     180           0 :                         r = radeon_fence_wait(fence, false);
     181           0 :                         if (r)
     182           0 :                                 return r;
     183           0 :                         continue;
     184             :                 }
     185             : 
     186             :                 /* we assume caller has already allocated space on waiters ring */
     187           0 :                 if (!radeon_semaphore_emit_wait(rdev, ring, semaphore)) {
     188             :                         /* waiting wasn't successful wait manually */
     189           0 :                         radeon_ring_undo(&rdev->ring[i]);
     190           0 :                         r = radeon_fence_wait(fence, false);
     191           0 :                         if (r)
     192           0 :                                 return r;
     193           0 :                         continue;
     194             :                 }
     195             : 
     196           0 :                 radeon_ring_commit(rdev, &rdev->ring[i], false);
     197           0 :                 radeon_fence_note_sync(fence, ring);
     198           0 :         }
     199             : 
     200           0 :         return 0;
     201           0 : }
     202             : 
     203             : /**
     204             :  * radeon_sync_free - free the sync object
     205             :  *
     206             :  * @rdev: radeon_device pointer
     207             :  * @sync: sync object to use
     208             :  * @fence: fence to use for the free
     209             :  *
     210             :  * Free the sync object by freeing all semaphores in it.
     211             :  */
     212           0 : void radeon_sync_free(struct radeon_device *rdev,
     213             :                       struct radeon_sync *sync,
     214             :                       struct radeon_fence *fence)
     215             : {
     216             :         unsigned i;
     217             : 
     218           0 :         for (i = 0; i < RADEON_NUM_SYNCS; ++i)
     219           0 :                 radeon_semaphore_free(rdev, &sync->semaphores[i], fence);
     220           0 : }

Generated by: LCOV version 1.13