LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/amdgpu - amdgpu_cs.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 695 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 29 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2008 Jerome Glisse.
       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 "Software"),
       7             :  * to deal in the Software without restriction, including without limitation
       8             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       9             :  * and/or sell copies of the Software, and to permit persons to whom the
      10             :  * Software is furnished to do so, subject to the following conditions:
      11             :  *
      12             :  * The above copyright notice and this permission notice (including the next
      13             :  * paragraph) shall be included in all copies or substantial portions of the
      14             :  * Software.
      15             :  *
      16             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      17             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      18             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      19             :  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
      20             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      21             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      22             :  * DEALINGS IN THE SOFTWARE.
      23             :  *
      24             :  * Authors:
      25             :  *    Jerome Glisse <glisse@freedesktop.org>
      26             :  */
      27             : 
      28             : #include <linux/file.h>
      29             : #include <linux/pagemap.h>
      30             : #include <linux/sync_file.h>
      31             : #include <linux/dma-buf.h>
      32             : 
      33             : #include <drm/amdgpu_drm.h>
      34             : #include <drm/drm_syncobj.h>
      35             : #include "amdgpu_cs.h"
      36             : #include "amdgpu.h"
      37             : #include "amdgpu_trace.h"
      38             : #include "amdgpu_gmc.h"
      39             : #include "amdgpu_gem.h"
      40             : #include "amdgpu_ras.h"
      41             : 
      42           0 : static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p,
      43             :                                       struct drm_amdgpu_cs_chunk_fence *data,
      44             :                                       uint32_t *offset)
      45             : {
      46             :         struct drm_gem_object *gobj;
      47             :         struct amdgpu_bo *bo;
      48             :         unsigned long size;
      49             :         int r;
      50             : 
      51           0 :         gobj = drm_gem_object_lookup(p->filp, data->handle);
      52           0 :         if (gobj == NULL)
      53             :                 return -EINVAL;
      54             : 
      55           0 :         bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
      56           0 :         p->uf_entry.priority = 0;
      57           0 :         p->uf_entry.tv.bo = &bo->tbo;
      58             :         /* One for TTM and two for the CS job */
      59           0 :         p->uf_entry.tv.num_shared = 3;
      60             : 
      61           0 :         drm_gem_object_put(gobj);
      62             : 
      63           0 :         size = amdgpu_bo_size(bo);
      64           0 :         if (size != PAGE_SIZE || (data->offset + 8) > size) {
      65             :                 r = -EINVAL;
      66             :                 goto error_unref;
      67             :         }
      68             : 
      69           0 :         if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) {
      70             :                 r = -EINVAL;
      71             :                 goto error_unref;
      72             :         }
      73             : 
      74           0 :         *offset = data->offset;
      75             : 
      76           0 :         return 0;
      77             : 
      78             : error_unref:
      79           0 :         amdgpu_bo_unref(&bo);
      80           0 :         return r;
      81             : }
      82             : 
      83           0 : static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p,
      84             :                                       struct drm_amdgpu_bo_list_in *data)
      85             : {
      86             :         int r;
      87           0 :         struct drm_amdgpu_bo_list_entry *info = NULL;
      88             : 
      89           0 :         r = amdgpu_bo_create_list_entry_array(data, &info);
      90           0 :         if (r)
      91             :                 return r;
      92             : 
      93           0 :         r = amdgpu_bo_list_create(p->adev, p->filp, info, data->bo_number,
      94             :                                   &p->bo_list);
      95           0 :         if (r)
      96             :                 goto error_free;
      97             : 
      98           0 :         kvfree(info);
      99           0 :         return 0;
     100             : 
     101             : error_free:
     102           0 :         kvfree(info);
     103             : 
     104           0 :         return r;
     105             : }
     106             : 
     107           0 : static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs)
     108             : {
     109           0 :         struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
     110           0 :         struct amdgpu_vm *vm = &fpriv->vm;
     111             :         uint64_t *chunk_array_user;
     112             :         uint64_t *chunk_array;
     113           0 :         unsigned size, num_ibs = 0;
     114           0 :         uint32_t uf_offset = 0;
     115             :         int i;
     116             :         int ret;
     117             : 
     118           0 :         if (cs->in.num_chunks == 0)
     119             :                 return -EINVAL;
     120             : 
     121           0 :         chunk_array = kvmalloc_array(cs->in.num_chunks, sizeof(uint64_t), GFP_KERNEL);
     122           0 :         if (!chunk_array)
     123             :                 return -ENOMEM;
     124             : 
     125           0 :         p->ctx = amdgpu_ctx_get(fpriv, cs->in.ctx_id);
     126           0 :         if (!p->ctx) {
     127             :                 ret = -EINVAL;
     128             :                 goto free_chunk;
     129             :         }
     130             : 
     131           0 :         mutex_lock(&p->ctx->lock);
     132             : 
     133             :         /* skip guilty context job */
     134           0 :         if (atomic_read(&p->ctx->guilty) == 1) {
     135             :                 ret = -ECANCELED;
     136             :                 goto free_chunk;
     137             :         }
     138             : 
     139             :         /* get chunks */
     140           0 :         chunk_array_user = u64_to_user_ptr(cs->in.chunks);
     141           0 :         if (copy_from_user(chunk_array, chunk_array_user,
     142           0 :                            sizeof(uint64_t)*cs->in.num_chunks)) {
     143             :                 ret = -EFAULT;
     144             :                 goto free_chunk;
     145             :         }
     146             : 
     147           0 :         p->nchunks = cs->in.num_chunks;
     148           0 :         p->chunks = kvmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk),
     149             :                             GFP_KERNEL);
     150           0 :         if (!p->chunks) {
     151             :                 ret = -ENOMEM;
     152             :                 goto free_chunk;
     153             :         }
     154             : 
     155           0 :         for (i = 0; i < p->nchunks; i++) {
     156           0 :                 struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL;
     157             :                 struct drm_amdgpu_cs_chunk user_chunk;
     158             :                 uint32_t __user *cdata;
     159             : 
     160           0 :                 chunk_ptr = u64_to_user_ptr(chunk_array[i]);
     161           0 :                 if (copy_from_user(&user_chunk, chunk_ptr,
     162             :                                        sizeof(struct drm_amdgpu_cs_chunk))) {
     163           0 :                         ret = -EFAULT;
     164           0 :                         i--;
     165           0 :                         goto free_partial_kdata;
     166             :                 }
     167           0 :                 p->chunks[i].chunk_id = user_chunk.chunk_id;
     168           0 :                 p->chunks[i].length_dw = user_chunk.length_dw;
     169             : 
     170           0 :                 size = p->chunks[i].length_dw;
     171           0 :                 cdata = u64_to_user_ptr(user_chunk.chunk_data);
     172             : 
     173           0 :                 p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL);
     174           0 :                 if (p->chunks[i].kdata == NULL) {
     175           0 :                         ret = -ENOMEM;
     176           0 :                         i--;
     177           0 :                         goto free_partial_kdata;
     178             :                 }
     179           0 :                 size *= sizeof(uint32_t);
     180           0 :                 if (copy_from_user(p->chunks[i].kdata, cdata, size)) {
     181             :                         ret = -EFAULT;
     182             :                         goto free_partial_kdata;
     183             :                 }
     184             : 
     185           0 :                 switch (p->chunks[i].chunk_id) {
     186             :                 case AMDGPU_CHUNK_ID_IB:
     187           0 :                         ++num_ibs;
     188           0 :                         break;
     189             : 
     190             :                 case AMDGPU_CHUNK_ID_FENCE:
     191           0 :                         size = sizeof(struct drm_amdgpu_cs_chunk_fence);
     192           0 :                         if (p->chunks[i].length_dw * sizeof(uint32_t) < size) {
     193             :                                 ret = -EINVAL;
     194             :                                 goto free_partial_kdata;
     195             :                         }
     196             : 
     197           0 :                         ret = amdgpu_cs_user_fence_chunk(p, p->chunks[i].kdata,
     198             :                                                          &uf_offset);
     199           0 :                         if (ret)
     200             :                                 goto free_partial_kdata;
     201             : 
     202             :                         break;
     203             : 
     204             :                 case AMDGPU_CHUNK_ID_BO_HANDLES:
     205           0 :                         size = sizeof(struct drm_amdgpu_bo_list_in);
     206           0 :                         if (p->chunks[i].length_dw * sizeof(uint32_t) < size) {
     207             :                                 ret = -EINVAL;
     208             :                                 goto free_partial_kdata;
     209             :                         }
     210             : 
     211           0 :                         ret = amdgpu_cs_bo_handles_chunk(p, p->chunks[i].kdata);
     212           0 :                         if (ret)
     213             :                                 goto free_partial_kdata;
     214             : 
     215             :                         break;
     216             : 
     217             :                 case AMDGPU_CHUNK_ID_DEPENDENCIES:
     218             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
     219             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
     220             :                 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
     221             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
     222             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
     223             :                         break;
     224             : 
     225             :                 default:
     226             :                         ret = -EINVAL;
     227             :                         goto free_partial_kdata;
     228             :                 }
     229             :         }
     230             : 
     231           0 :         ret = amdgpu_job_alloc(p->adev, num_ibs, &p->job, vm);
     232           0 :         if (ret)
     233             :                 goto free_all_kdata;
     234             : 
     235           0 :         if (p->ctx->vram_lost_counter != p->job->vram_lost_counter) {
     236             :                 ret = -ECANCELED;
     237             :                 goto free_all_kdata;
     238             :         }
     239             : 
     240           0 :         if (p->uf_entry.tv.bo)
     241           0 :                 p->job->uf_addr = uf_offset;
     242           0 :         kvfree(chunk_array);
     243             : 
     244             :         /* Use this opportunity to fill in task info for the vm */
     245           0 :         amdgpu_vm_set_task_info(vm);
     246             : 
     247           0 :         return 0;
     248             : 
     249             : free_all_kdata:
     250           0 :         i = p->nchunks - 1;
     251             : free_partial_kdata:
     252           0 :         for (; i >= 0; i--)
     253           0 :                 kvfree(p->chunks[i].kdata);
     254           0 :         kvfree(p->chunks);
     255           0 :         p->chunks = NULL;
     256           0 :         p->nchunks = 0;
     257             : free_chunk:
     258           0 :         kvfree(chunk_array);
     259             : 
     260           0 :         return ret;
     261             : }
     262             : 
     263             : /* Convert microseconds to bytes. */
     264             : static u64 us_to_bytes(struct amdgpu_device *adev, s64 us)
     265             : {
     266           0 :         if (us <= 0 || !adev->mm_stats.log2_max_MBps)
     267             :                 return 0;
     268             : 
     269             :         /* Since accum_us is incremented by a million per second, just
     270             :          * multiply it by the number of MB/s to get the number of bytes.
     271             :          */
     272           0 :         return us << adev->mm_stats.log2_max_MBps;
     273             : }
     274             : 
     275             : static s64 bytes_to_us(struct amdgpu_device *adev, u64 bytes)
     276             : {
     277           0 :         if (!adev->mm_stats.log2_max_MBps)
     278             :                 return 0;
     279             : 
     280           0 :         return bytes >> adev->mm_stats.log2_max_MBps;
     281             : }
     282             : 
     283             : /* Returns how many bytes TTM can move right now. If no bytes can be moved,
     284             :  * it returns 0. If it returns non-zero, it's OK to move at least one buffer,
     285             :  * which means it can go over the threshold once. If that happens, the driver
     286             :  * will be in debt and no other buffer migrations can be done until that debt
     287             :  * is repaid.
     288             :  *
     289             :  * This approach allows moving a buffer of any size (it's important to allow
     290             :  * that).
     291             :  *
     292             :  * The currency is simply time in microseconds and it increases as the clock
     293             :  * ticks. The accumulated microseconds (us) are converted to bytes and
     294             :  * returned.
     295             :  */
     296           0 : static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev,
     297             :                                               u64 *max_bytes,
     298             :                                               u64 *max_vis_bytes)
     299             : {
     300             :         s64 time_us, increment_us;
     301             :         u64 free_vram, total_vram, used_vram;
     302             :         /* Allow a maximum of 200 accumulated ms. This is basically per-IB
     303             :          * throttling.
     304             :          *
     305             :          * It means that in order to get full max MBps, at least 5 IBs per
     306             :          * second must be submitted and not more than 200ms apart from each
     307             :          * other.
     308             :          */
     309           0 :         const s64 us_upper_bound = 200000;
     310             : 
     311           0 :         if (!adev->mm_stats.log2_max_MBps) {
     312           0 :                 *max_bytes = 0;
     313           0 :                 *max_vis_bytes = 0;
     314           0 :                 return;
     315             :         }
     316             : 
     317           0 :         total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size);
     318           0 :         used_vram = ttm_resource_manager_usage(&adev->mman.vram_mgr.manager);
     319           0 :         free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
     320             : 
     321           0 :         spin_lock(&adev->mm_stats.lock);
     322             : 
     323             :         /* Increase the amount of accumulated us. */
     324           0 :         time_us = ktime_to_us(ktime_get());
     325           0 :         increment_us = time_us - adev->mm_stats.last_update_us;
     326           0 :         adev->mm_stats.last_update_us = time_us;
     327           0 :         adev->mm_stats.accum_us = min(adev->mm_stats.accum_us + increment_us,
     328             :                                       us_upper_bound);
     329             : 
     330             :         /* This prevents the short period of low performance when the VRAM
     331             :          * usage is low and the driver is in debt or doesn't have enough
     332             :          * accumulated us to fill VRAM quickly.
     333             :          *
     334             :          * The situation can occur in these cases:
     335             :          * - a lot of VRAM is freed by userspace
     336             :          * - the presence of a big buffer causes a lot of evictions
     337             :          *   (solution: split buffers into smaller ones)
     338             :          *
     339             :          * If 128 MB or 1/8th of VRAM is free, start filling it now by setting
     340             :          * accum_us to a positive number.
     341             :          */
     342           0 :         if (free_vram >= 128 * 1024 * 1024 || free_vram >= total_vram / 8) {
     343             :                 s64 min_us;
     344             : 
     345             :                 /* Be more aggressive on dGPUs. Try to fill a portion of free
     346             :                  * VRAM now.
     347             :                  */
     348           0 :                 if (!(adev->flags & AMD_IS_APU))
     349           0 :                         min_us = bytes_to_us(adev, free_vram / 4);
     350             :                 else
     351             :                         min_us = 0; /* Reset accum_us on APUs. */
     352             : 
     353           0 :                 adev->mm_stats.accum_us = max(min_us, adev->mm_stats.accum_us);
     354             :         }
     355             : 
     356             :         /* This is set to 0 if the driver is in debt to disallow (optional)
     357             :          * buffer moves.
     358             :          */
     359           0 :         *max_bytes = us_to_bytes(adev, adev->mm_stats.accum_us);
     360             : 
     361             :         /* Do the same for visible VRAM if half of it is free */
     362           0 :         if (!amdgpu_gmc_vram_full_visible(&adev->gmc)) {
     363           0 :                 u64 total_vis_vram = adev->gmc.visible_vram_size;
     364           0 :                 u64 used_vis_vram =
     365           0 :                   amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr);
     366             : 
     367           0 :                 if (used_vis_vram < total_vis_vram) {
     368           0 :                         u64 free_vis_vram = total_vis_vram - used_vis_vram;
     369           0 :                         adev->mm_stats.accum_us_vis = min(adev->mm_stats.accum_us_vis +
     370             :                                                           increment_us, us_upper_bound);
     371             : 
     372           0 :                         if (free_vis_vram >= total_vis_vram / 2)
     373           0 :                                 adev->mm_stats.accum_us_vis =
     374           0 :                                         max(bytes_to_us(adev, free_vis_vram / 2),
     375             :                                             adev->mm_stats.accum_us_vis);
     376             :                 }
     377             : 
     378           0 :                 *max_vis_bytes = us_to_bytes(adev, adev->mm_stats.accum_us_vis);
     379             :         } else {
     380           0 :                 *max_vis_bytes = 0;
     381             :         }
     382             : 
     383           0 :         spin_unlock(&adev->mm_stats.lock);
     384             : }
     385             : 
     386             : /* Report how many bytes have really been moved for the last command
     387             :  * submission. This can result in a debt that can stop buffer migrations
     388             :  * temporarily.
     389             :  */
     390           0 : void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
     391             :                                   u64 num_vis_bytes)
     392             : {
     393           0 :         spin_lock(&adev->mm_stats.lock);
     394           0 :         adev->mm_stats.accum_us -= bytes_to_us(adev, num_bytes);
     395           0 :         adev->mm_stats.accum_us_vis -= bytes_to_us(adev, num_vis_bytes);
     396           0 :         spin_unlock(&adev->mm_stats.lock);
     397           0 : }
     398             : 
     399           0 : static int amdgpu_cs_bo_validate(void *param, struct amdgpu_bo *bo)
     400             : {
     401           0 :         struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
     402           0 :         struct amdgpu_cs_parser *p = param;
     403           0 :         struct ttm_operation_ctx ctx = {
     404             :                 .interruptible = true,
     405             :                 .no_wait_gpu = false,
     406           0 :                 .resv = bo->tbo.base.resv
     407             :         };
     408             :         uint32_t domain;
     409             :         int r;
     410             : 
     411           0 :         if (bo->tbo.pin_count)
     412             :                 return 0;
     413             : 
     414             :         /* Don't move this buffer if we have depleted our allowance
     415             :          * to move it. Don't move anything if the threshold is zero.
     416             :          */
     417           0 :         if (p->bytes_moved < p->bytes_moved_threshold &&
     418           0 :             (!bo->tbo.base.dma_buf ||
     419           0 :             list_empty(&bo->tbo.base.dma_buf->attachments))) {
     420           0 :                 if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
     421           0 :                     (bo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED)) {
     422             :                         /* And don't move a CPU_ACCESS_REQUIRED BO to limited
     423             :                          * visible VRAM if we've depleted our allowance to do
     424             :                          * that.
     425             :                          */
     426           0 :                         if (p->bytes_moved_vis < p->bytes_moved_vis_threshold)
     427           0 :                                 domain = bo->preferred_domains;
     428             :                         else
     429           0 :                                 domain = bo->allowed_domains;
     430             :                 } else {
     431           0 :                         domain = bo->preferred_domains;
     432             :                 }
     433             :         } else {
     434           0 :                 domain = bo->allowed_domains;
     435             :         }
     436             : 
     437             : retry:
     438           0 :         amdgpu_bo_placement_from_domain(bo, domain);
     439           0 :         r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
     440             : 
     441           0 :         p->bytes_moved += ctx.bytes_moved;
     442           0 :         if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
     443           0 :             amdgpu_bo_in_cpu_visible_vram(bo))
     444           0 :                 p->bytes_moved_vis += ctx.bytes_moved;
     445             : 
     446           0 :         if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
     447             :                 domain = bo->allowed_domains;
     448             :                 goto retry;
     449             :         }
     450             : 
     451             :         return r;
     452             : }
     453             : 
     454           0 : static int amdgpu_cs_list_validate(struct amdgpu_cs_parser *p,
     455             :                             struct list_head *validated)
     456             : {
     457           0 :         struct ttm_operation_ctx ctx = { true, false };
     458             :         struct amdgpu_bo_list_entry *lobj;
     459             :         int r;
     460             : 
     461           0 :         list_for_each_entry(lobj, validated, tv.head) {
     462           0 :                 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
     463             :                 struct mm_struct *usermm;
     464             : 
     465           0 :                 usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
     466           0 :                 if (usermm && usermm != current->mm)
     467             :                         return -EPERM;
     468             : 
     469           0 :                 if (amdgpu_ttm_tt_is_userptr(bo->tbo.ttm) &&
     470           0 :                     lobj->user_invalidated && lobj->user_pages) {
     471           0 :                         amdgpu_bo_placement_from_domain(bo,
     472             :                                                         AMDGPU_GEM_DOMAIN_CPU);
     473           0 :                         r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
     474           0 :                         if (r)
     475             :                                 return r;
     476             : 
     477           0 :                         amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
     478             :                                                      lobj->user_pages);
     479             :                 }
     480             : 
     481           0 :                 r = amdgpu_cs_bo_validate(p, bo);
     482           0 :                 if (r)
     483             :                         return r;
     484             : 
     485           0 :                 kvfree(lobj->user_pages);
     486           0 :                 lobj->user_pages = NULL;
     487             :         }
     488             :         return 0;
     489             : }
     490             : 
     491           0 : static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
     492             :                                 union drm_amdgpu_cs *cs)
     493             : {
     494           0 :         struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
     495           0 :         struct amdgpu_vm *vm = &fpriv->vm;
     496             :         struct amdgpu_bo_list_entry *e;
     497             :         struct list_head duplicates;
     498             :         struct amdgpu_bo *gds;
     499             :         struct amdgpu_bo *gws;
     500             :         struct amdgpu_bo *oa;
     501             :         int r;
     502             : 
     503           0 :         INIT_LIST_HEAD(&p->validated);
     504             : 
     505             :         /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */
     506           0 :         if (cs->in.bo_list_handle) {
     507           0 :                 if (p->bo_list)
     508             :                         return -EINVAL;
     509             : 
     510           0 :                 r = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle,
     511             :                                        &p->bo_list);
     512           0 :                 if (r)
     513             :                         return r;
     514           0 :         } else if (!p->bo_list) {
     515             :                 /* Create a empty bo_list when no handle is provided */
     516           0 :                 r = amdgpu_bo_list_create(p->adev, p->filp, NULL, 0,
     517             :                                           &p->bo_list);
     518           0 :                 if (r)
     519             :                         return r;
     520             :         }
     521             : 
     522           0 :         mutex_lock(&p->bo_list->bo_list_mutex);
     523             : 
     524             :         /* One for TTM and one for the CS job */
     525           0 :         amdgpu_bo_list_for_each_entry(e, p->bo_list)
     526           0 :                 e->tv.num_shared = 2;
     527             : 
     528           0 :         amdgpu_bo_list_get_list(p->bo_list, &p->validated);
     529             : 
     530           0 :         INIT_LIST_HEAD(&duplicates);
     531           0 :         amdgpu_vm_get_pd_bo(&fpriv->vm, &p->validated, &p->vm_pd);
     532             : 
     533           0 :         if (p->uf_entry.tv.bo && !ttm_to_amdgpu_bo(p->uf_entry.tv.bo)->parent)
     534           0 :                 list_add(&p->uf_entry.tv.head, &p->validated);
     535             : 
     536             :         /* Get userptr backing pages. If pages are updated after registered
     537             :          * in amdgpu_gem_userptr_ioctl(), amdgpu_cs_list_validate() will do
     538             :          * amdgpu_ttm_backend_bind() to flush and invalidate new pages
     539             :          */
     540           0 :         amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
     541           0 :                 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
     542           0 :                 bool userpage_invalidated = false;
     543             :                 int i;
     544             : 
     545           0 :                 e->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
     546             :                                         sizeof(struct page *),
     547             :                                         GFP_KERNEL | __GFP_ZERO);
     548           0 :                 if (!e->user_pages) {
     549           0 :                         DRM_ERROR("kvmalloc_array failure\n");
     550           0 :                         r = -ENOMEM;
     551             :                         goto out_free_user_pages;
     552             :                 }
     553             : 
     554           0 :                 r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages);
     555             :                 if (r) {
     556           0 :                         kvfree(e->user_pages);
     557           0 :                         e->user_pages = NULL;
     558             :                         goto out_free_user_pages;
     559             :                 }
     560             : 
     561             :                 for (i = 0; i < bo->tbo.ttm->num_pages; i++) {
     562             :                         if (bo->tbo.ttm->pages[i] != e->user_pages[i]) {
     563             :                                 userpage_invalidated = true;
     564             :                                 break;
     565             :                         }
     566             :                 }
     567             :                 e->user_invalidated = userpage_invalidated;
     568             :         }
     569             : 
     570           0 :         r = ttm_eu_reserve_buffers(&p->ticket, &p->validated, true,
     571             :                                    &duplicates);
     572           0 :         if (unlikely(r != 0)) {
     573           0 :                 if (r != -ERESTARTSYS)
     574           0 :                         DRM_ERROR("ttm_eu_reserve_buffers failed.\n");
     575             :                 goto out_free_user_pages;
     576             :         }
     577             : 
     578           0 :         amdgpu_bo_list_for_each_entry(e, p->bo_list) {
     579           0 :                 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
     580             : 
     581           0 :                 e->bo_va = amdgpu_vm_bo_find(vm, bo);
     582             :         }
     583             : 
     584             :         /* Move fence waiting after getting reservation lock of
     585             :          * PD root. Then there is no need on a ctx mutex lock.
     586             :          */
     587           0 :         r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entity);
     588           0 :         if (unlikely(r != 0)) {
     589           0 :                 if (r != -ERESTARTSYS)
     590           0 :                         DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n");
     591             :                 goto error_validate;
     592             :         }
     593             : 
     594           0 :         amdgpu_cs_get_threshold_for_moves(p->adev, &p->bytes_moved_threshold,
     595           0 :                                           &p->bytes_moved_vis_threshold);
     596           0 :         p->bytes_moved = 0;
     597           0 :         p->bytes_moved_vis = 0;
     598             : 
     599           0 :         r = amdgpu_vm_validate_pt_bos(p->adev, &fpriv->vm,
     600             :                                       amdgpu_cs_bo_validate, p);
     601           0 :         if (r) {
     602           0 :                 DRM_ERROR("amdgpu_vm_validate_pt_bos() failed.\n");
     603             :                 goto error_validate;
     604             :         }
     605             : 
     606           0 :         r = amdgpu_cs_list_validate(p, &duplicates);
     607           0 :         if (r)
     608             :                 goto error_validate;
     609             : 
     610           0 :         r = amdgpu_cs_list_validate(p, &p->validated);
     611           0 :         if (r)
     612             :                 goto error_validate;
     613             : 
     614           0 :         amdgpu_cs_report_moved_bytes(p->adev, p->bytes_moved,
     615             :                                      p->bytes_moved_vis);
     616             : 
     617           0 :         gds = p->bo_list->gds_obj;
     618           0 :         gws = p->bo_list->gws_obj;
     619           0 :         oa = p->bo_list->oa_obj;
     620             : 
     621           0 :         if (gds) {
     622           0 :                 p->job->gds_base = amdgpu_bo_gpu_offset(gds) >> PAGE_SHIFT;
     623           0 :                 p->job->gds_size = amdgpu_bo_size(gds) >> PAGE_SHIFT;
     624             :         }
     625           0 :         if (gws) {
     626           0 :                 p->job->gws_base = amdgpu_bo_gpu_offset(gws) >> PAGE_SHIFT;
     627           0 :                 p->job->gws_size = amdgpu_bo_size(gws) >> PAGE_SHIFT;
     628             :         }
     629           0 :         if (oa) {
     630           0 :                 p->job->oa_base = amdgpu_bo_gpu_offset(oa) >> PAGE_SHIFT;
     631           0 :                 p->job->oa_size = amdgpu_bo_size(oa) >> PAGE_SHIFT;
     632             :         }
     633             : 
     634           0 :         if (!r && p->uf_entry.tv.bo) {
     635           0 :                 struct amdgpu_bo *uf = ttm_to_amdgpu_bo(p->uf_entry.tv.bo);
     636             : 
     637           0 :                 r = amdgpu_ttm_alloc_gart(&uf->tbo);
     638           0 :                 p->job->uf_addr += amdgpu_bo_gpu_offset(uf);
     639             :         }
     640             : 
     641             : error_validate:
     642           0 :         if (r)
     643           0 :                 ttm_eu_backoff_reservation(&p->ticket, &p->validated);
     644             : 
     645             : out_free_user_pages:
     646           0 :         if (r) {
     647           0 :                 amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
     648           0 :                         struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
     649             : 
     650           0 :                         if (!e->user_pages)
     651           0 :                                 continue;
     652           0 :                         amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
     653           0 :                         kvfree(e->user_pages);
     654           0 :                         e->user_pages = NULL;
     655             :                 }
     656           0 :                 mutex_unlock(&p->bo_list->bo_list_mutex);
     657             :         }
     658             :         return r;
     659             : }
     660             : 
     661           0 : static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p)
     662             : {
     663           0 :         struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
     664             :         struct amdgpu_bo_list_entry *e;
     665             :         int r;
     666             : 
     667           0 :         list_for_each_entry(e, &p->validated, tv.head) {
     668           0 :                 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
     669           0 :                 struct dma_resv *resv = bo->tbo.base.resv;
     670             :                 enum amdgpu_sync_mode sync_mode;
     671             : 
     672           0 :                 sync_mode = amdgpu_bo_explicit_sync(bo) ?
     673           0 :                         AMDGPU_SYNC_EXPLICIT : AMDGPU_SYNC_NE_OWNER;
     674           0 :                 r = amdgpu_sync_resv(p->adev, &p->job->sync, resv, sync_mode,
     675           0 :                                      &fpriv->vm);
     676           0 :                 if (r)
     677             :                         return r;
     678             :         }
     679             :         return 0;
     680             : }
     681             : 
     682             : /**
     683             :  * amdgpu_cs_parser_fini() - clean parser states
     684             :  * @parser:     parser structure holding parsing context.
     685             :  * @error:      error number
     686             :  * @backoff:    indicator to backoff the reservation
     687             :  *
     688             :  * If error is set then unvalidate buffer, otherwise just free memory
     689             :  * used by parsing context.
     690             :  **/
     691           0 : static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
     692             :                                   bool backoff)
     693             : {
     694             :         unsigned i;
     695             : 
     696           0 :         if (error && backoff) {
     697           0 :                 ttm_eu_backoff_reservation(&parser->ticket,
     698             :                                            &parser->validated);
     699           0 :                 mutex_unlock(&parser->bo_list->bo_list_mutex);
     700             :         }
     701             : 
     702           0 :         for (i = 0; i < parser->num_post_deps; i++) {
     703           0 :                 drm_syncobj_put(parser->post_deps[i].syncobj);
     704           0 :                 kfree(parser->post_deps[i].chain);
     705             :         }
     706           0 :         kfree(parser->post_deps);
     707             : 
     708           0 :         dma_fence_put(parser->fence);
     709             : 
     710           0 :         if (parser->ctx) {
     711           0 :                 mutex_unlock(&parser->ctx->lock);
     712           0 :                 amdgpu_ctx_put(parser->ctx);
     713             :         }
     714           0 :         if (parser->bo_list)
     715           0 :                 amdgpu_bo_list_put(parser->bo_list);
     716             : 
     717           0 :         for (i = 0; i < parser->nchunks; i++)
     718           0 :                 kvfree(parser->chunks[i].kdata);
     719           0 :         kvfree(parser->chunks);
     720           0 :         if (parser->job)
     721           0 :                 amdgpu_job_free(parser->job);
     722           0 :         if (parser->uf_entry.tv.bo) {
     723           0 :                 struct amdgpu_bo *uf = ttm_to_amdgpu_bo(parser->uf_entry.tv.bo);
     724             : 
     725           0 :                 amdgpu_bo_unref(&uf);
     726             :         }
     727           0 : }
     728             : 
     729           0 : static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
     730             : {
     731           0 :         struct amdgpu_ring *ring = to_amdgpu_ring(p->entity->rq->sched);
     732           0 :         struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
     733           0 :         struct amdgpu_device *adev = p->adev;
     734           0 :         struct amdgpu_vm *vm = &fpriv->vm;
     735             :         struct amdgpu_bo_list_entry *e;
     736             :         struct amdgpu_bo_va *bo_va;
     737             :         struct amdgpu_bo *bo;
     738             :         int r;
     739             : 
     740             :         /* Only for UVD/VCE VM emulation */
     741           0 :         if (ring->funcs->parse_cs || ring->funcs->patch_cs_in_place) {
     742             :                 unsigned i, j;
     743             : 
     744           0 :                 for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) {
     745             :                         struct drm_amdgpu_cs_chunk_ib *chunk_ib;
     746             :                         struct amdgpu_bo_va_mapping *m;
     747           0 :                         struct amdgpu_bo *aobj = NULL;
     748             :                         struct amdgpu_cs_chunk *chunk;
     749             :                         uint64_t offset, va_start;
     750             :                         struct amdgpu_ib *ib;
     751             :                         uint8_t *kptr;
     752             : 
     753           0 :                         chunk = &p->chunks[i];
     754           0 :                         ib = &p->job->ibs[j];
     755           0 :                         chunk_ib = chunk->kdata;
     756             : 
     757           0 :                         if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
     758           0 :                                 continue;
     759             : 
     760           0 :                         va_start = chunk_ib->va_start & AMDGPU_GMC_HOLE_MASK;
     761           0 :                         r = amdgpu_cs_find_mapping(p, va_start, &aobj, &m);
     762           0 :                         if (r) {
     763           0 :                                 DRM_ERROR("IB va_start is invalid\n");
     764           0 :                                 return r;
     765             :                         }
     766             : 
     767           0 :                         if ((va_start + chunk_ib->ib_bytes) >
     768           0 :                             (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) {
     769           0 :                                 DRM_ERROR("IB va_start+ib_bytes is invalid\n");
     770           0 :                                 return -EINVAL;
     771             :                         }
     772             : 
     773             :                         /* the IB should be reserved at this point */
     774           0 :                         r = amdgpu_bo_kmap(aobj, (void **)&kptr);
     775           0 :                         if (r) {
     776             :                                 return r;
     777             :                         }
     778             : 
     779           0 :                         offset = m->start * AMDGPU_GPU_PAGE_SIZE;
     780           0 :                         kptr += va_start - offset;
     781             : 
     782           0 :                         if (ring->funcs->parse_cs) {
     783           0 :                                 memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
     784           0 :                                 amdgpu_bo_kunmap(aobj);
     785             : 
     786           0 :                                 r = amdgpu_ring_parse_cs(ring, p, p->job, ib);
     787           0 :                                 if (r)
     788             :                                         return r;
     789             :                         } else {
     790           0 :                                 ib->ptr = (uint32_t *)kptr;
     791           0 :                                 r = amdgpu_ring_patch_cs_in_place(ring, p, p->job, ib);
     792           0 :                                 amdgpu_bo_kunmap(aobj);
     793           0 :                                 if (r)
     794             :                                         return r;
     795             :                         }
     796             : 
     797           0 :                         j++;
     798             :                 }
     799             :         }
     800             : 
     801           0 :         if (!p->job->vm)
     802           0 :                 return amdgpu_cs_sync_rings(p);
     803             : 
     804             : 
     805           0 :         r = amdgpu_vm_clear_freed(adev, vm, NULL);
     806           0 :         if (r)
     807             :                 return r;
     808             : 
     809           0 :         r = amdgpu_vm_bo_update(adev, fpriv->prt_va, false);
     810           0 :         if (r)
     811             :                 return r;
     812             : 
     813           0 :         r = amdgpu_sync_fence(&p->job->sync, fpriv->prt_va->last_pt_update);
     814           0 :         if (r)
     815             :                 return r;
     816             : 
     817           0 :         if (amdgpu_mcbp || amdgpu_sriov_vf(adev)) {
     818           0 :                 bo_va = fpriv->csa_va;
     819           0 :                 BUG_ON(!bo_va);
     820           0 :                 r = amdgpu_vm_bo_update(adev, bo_va, false);
     821           0 :                 if (r)
     822             :                         return r;
     823             : 
     824           0 :                 r = amdgpu_sync_fence(&p->job->sync, bo_va->last_pt_update);
     825           0 :                 if (r)
     826             :                         return r;
     827             :         }
     828             : 
     829           0 :         amdgpu_bo_list_for_each_entry(e, p->bo_list) {
     830             :                 /* ignore duplicates */
     831           0 :                 bo = ttm_to_amdgpu_bo(e->tv.bo);
     832           0 :                 if (!bo)
     833           0 :                         continue;
     834             : 
     835           0 :                 bo_va = e->bo_va;
     836           0 :                 if (bo_va == NULL)
     837           0 :                         continue;
     838             : 
     839           0 :                 r = amdgpu_vm_bo_update(adev, bo_va, false);
     840           0 :                 if (r)
     841             :                         return r;
     842             : 
     843           0 :                 r = amdgpu_sync_fence(&p->job->sync, bo_va->last_pt_update);
     844           0 :                 if (r)
     845             :                         return r;
     846             :         }
     847             : 
     848           0 :         r = amdgpu_vm_handle_moved(adev, vm);
     849           0 :         if (r)
     850             :                 return r;
     851             : 
     852           0 :         r = amdgpu_vm_update_pdes(adev, vm, false);
     853           0 :         if (r)
     854             :                 return r;
     855             : 
     856           0 :         r = amdgpu_sync_fence(&p->job->sync, vm->last_update);
     857           0 :         if (r)
     858             :                 return r;
     859             : 
     860           0 :         p->job->vm_pd_addr = amdgpu_gmc_pd_addr(vm->root.bo);
     861             : 
     862           0 :         if (amdgpu_vm_debug) {
     863             :                 /* Invalidate all BOs to test for userspace bugs */
     864           0 :                 amdgpu_bo_list_for_each_entry(e, p->bo_list) {
     865           0 :                         struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
     866             : 
     867             :                         /* ignore duplicates */
     868           0 :                         if (!bo)
     869           0 :                                 continue;
     870             : 
     871           0 :                         amdgpu_vm_bo_invalidate(adev, bo, false);
     872             :                 }
     873             :         }
     874             : 
     875           0 :         return amdgpu_cs_sync_rings(p);
     876             : }
     877             : 
     878           0 : static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
     879             :                              struct amdgpu_cs_parser *parser)
     880             : {
     881           0 :         struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
     882           0 :         struct amdgpu_vm *vm = &fpriv->vm;
     883           0 :         int r, ce_preempt = 0, de_preempt = 0;
     884             :         struct amdgpu_ring *ring;
     885             :         int i, j;
     886             : 
     887           0 :         for (i = 0, j = 0; i < parser->nchunks && j < parser->job->num_ibs; i++) {
     888             :                 struct amdgpu_cs_chunk *chunk;
     889             :                 struct amdgpu_ib *ib;
     890             :                 struct drm_amdgpu_cs_chunk_ib *chunk_ib;
     891             :                 struct drm_sched_entity *entity;
     892             : 
     893           0 :                 chunk = &parser->chunks[i];
     894           0 :                 ib = &parser->job->ibs[j];
     895           0 :                 chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata;
     896             : 
     897           0 :                 if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
     898           0 :                         continue;
     899             : 
     900           0 :                 if (chunk_ib->ip_type == AMDGPU_HW_IP_GFX &&
     901           0 :                     (amdgpu_mcbp || amdgpu_sriov_vf(adev))) {
     902           0 :                         if (chunk_ib->flags & AMDGPU_IB_FLAG_PREEMPT) {
     903           0 :                                 if (chunk_ib->flags & AMDGPU_IB_FLAG_CE)
     904           0 :                                         ce_preempt++;
     905             :                                 else
     906           0 :                                         de_preempt++;
     907             :                         }
     908             : 
     909             :                         /* each GFX command submit allows 0 or 1 IB preemptible for CE & DE */
     910           0 :                         if (ce_preempt > 1 || de_preempt > 1)
     911           0 :                                 return -EINVAL;
     912             :                 }
     913             : 
     914           0 :                 r = amdgpu_ctx_get_entity(parser->ctx, chunk_ib->ip_type,
     915             :                                           chunk_ib->ip_instance, chunk_ib->ring,
     916             :                                           &entity);
     917           0 :                 if (r)
     918             :                         return r;
     919             : 
     920           0 :                 if (chunk_ib->flags & AMDGPU_IB_FLAG_PREAMBLE)
     921           0 :                         parser->job->preamble_status |=
     922             :                                 AMDGPU_PREAMBLE_IB_PRESENT;
     923             : 
     924           0 :                 if (parser->entity && parser->entity != entity)
     925             :                         return -EINVAL;
     926             : 
     927             :                 /* Return if there is no run queue associated with this entity.
     928             :                  * Possibly because of disabled HW IP*/
     929           0 :                 if (entity->rq == NULL)
     930             :                         return -EINVAL;
     931             : 
     932           0 :                 parser->entity = entity;
     933             : 
     934           0 :                 ring = to_amdgpu_ring(entity->rq->sched);
     935           0 :                 r =  amdgpu_ib_get(adev, vm, ring->funcs->parse_cs ?
     936             :                                    chunk_ib->ib_bytes : 0,
     937             :                                    AMDGPU_IB_POOL_DELAYED, ib);
     938           0 :                 if (r) {
     939           0 :                         DRM_ERROR("Failed to get ib !\n");
     940           0 :                         return r;
     941             :                 }
     942             : 
     943           0 :                 ib->gpu_addr = chunk_ib->va_start;
     944           0 :                 ib->length_dw = chunk_ib->ib_bytes / 4;
     945           0 :                 ib->flags = chunk_ib->flags;
     946             : 
     947           0 :                 j++;
     948             :         }
     949             : 
     950             :         /* MM engine doesn't support user fences */
     951           0 :         ring = to_amdgpu_ring(parser->entity->rq->sched);
     952           0 :         if (parser->job->uf_addr && ring->funcs->no_user_fence)
     953             :                 return -EINVAL;
     954             : 
     955           0 :         return 0;
     956             : }
     957             : 
     958           0 : static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p,
     959             :                                        struct amdgpu_cs_chunk *chunk)
     960             : {
     961           0 :         struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
     962             :         unsigned num_deps;
     963             :         int i, r;
     964             :         struct drm_amdgpu_cs_chunk_dep *deps;
     965             : 
     966           0 :         deps = (struct drm_amdgpu_cs_chunk_dep *)chunk->kdata;
     967           0 :         num_deps = chunk->length_dw * 4 /
     968             :                 sizeof(struct drm_amdgpu_cs_chunk_dep);
     969             : 
     970           0 :         for (i = 0; i < num_deps; ++i) {
     971             :                 struct amdgpu_ctx *ctx;
     972             :                 struct drm_sched_entity *entity;
     973             :                 struct dma_fence *fence;
     974             : 
     975           0 :                 ctx = amdgpu_ctx_get(fpriv, deps[i].ctx_id);
     976           0 :                 if (ctx == NULL)
     977           0 :                         return -EINVAL;
     978             : 
     979           0 :                 r = amdgpu_ctx_get_entity(ctx, deps[i].ip_type,
     980             :                                           deps[i].ip_instance,
     981             :                                           deps[i].ring, &entity);
     982           0 :                 if (r) {
     983           0 :                         amdgpu_ctx_put(ctx);
     984             :                         return r;
     985             :                 }
     986             : 
     987           0 :                 fence = amdgpu_ctx_get_fence(ctx, entity, deps[i].handle);
     988           0 :                 amdgpu_ctx_put(ctx);
     989             : 
     990           0 :                 if (IS_ERR(fence))
     991           0 :                         return PTR_ERR(fence);
     992           0 :                 else if (!fence)
     993           0 :                         continue;
     994             : 
     995           0 :                 if (chunk->chunk_id == AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES) {
     996             :                         struct drm_sched_fence *s_fence;
     997           0 :                         struct dma_fence *old = fence;
     998             : 
     999           0 :                         s_fence = to_drm_sched_fence(fence);
    1000           0 :                         fence = dma_fence_get(&s_fence->scheduled);
    1001             :                         dma_fence_put(old);
    1002             :                 }
    1003             : 
    1004           0 :                 r = amdgpu_sync_fence(&p->job->sync, fence);
    1005           0 :                 dma_fence_put(fence);
    1006           0 :                 if (r)
    1007             :                         return r;
    1008             :         }
    1009             :         return 0;
    1010             : }
    1011             : 
    1012           0 : static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
    1013             :                                                  uint32_t handle, u64 point,
    1014             :                                                  u64 flags)
    1015             : {
    1016             :         struct dma_fence *fence;
    1017             :         int r;
    1018             : 
    1019           0 :         r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence);
    1020           0 :         if (r) {
    1021           0 :                 DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n",
    1022             :                           handle, point, r);
    1023             :                 return r;
    1024             :         }
    1025             : 
    1026           0 :         r = amdgpu_sync_fence(&p->job->sync, fence);
    1027           0 :         dma_fence_put(fence);
    1028             : 
    1029             :         return r;
    1030             : }
    1031             : 
    1032           0 : static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
    1033             :                                             struct amdgpu_cs_chunk *chunk)
    1034             : {
    1035             :         struct drm_amdgpu_cs_chunk_sem *deps;
    1036             :         unsigned num_deps;
    1037             :         int i, r;
    1038             : 
    1039           0 :         deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
    1040           0 :         num_deps = chunk->length_dw * 4 /
    1041             :                 sizeof(struct drm_amdgpu_cs_chunk_sem);
    1042           0 :         for (i = 0; i < num_deps; ++i) {
    1043           0 :                 r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle,
    1044             :                                                           0, 0);
    1045           0 :                 if (r)
    1046             :                         return r;
    1047             :         }
    1048             : 
    1049             :         return 0;
    1050             : }
    1051             : 
    1052             : 
    1053           0 : static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser *p,
    1054             :                                                      struct amdgpu_cs_chunk *chunk)
    1055             : {
    1056             :         struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
    1057             :         unsigned num_deps;
    1058             :         int i, r;
    1059             : 
    1060           0 :         syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
    1061           0 :         num_deps = chunk->length_dw * 4 /
    1062             :                 sizeof(struct drm_amdgpu_cs_chunk_syncobj);
    1063           0 :         for (i = 0; i < num_deps; ++i) {
    1064           0 :                 r = amdgpu_syncobj_lookup_and_add_to_sync(p,
    1065             :                                                           syncobj_deps[i].handle,
    1066             :                                                           syncobj_deps[i].point,
    1067           0 :                                                           syncobj_deps[i].flags);
    1068           0 :                 if (r)
    1069             :                         return r;
    1070             :         }
    1071             : 
    1072             :         return 0;
    1073             : }
    1074             : 
    1075           0 : static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
    1076             :                                              struct amdgpu_cs_chunk *chunk)
    1077             : {
    1078             :         struct drm_amdgpu_cs_chunk_sem *deps;
    1079             :         unsigned num_deps;
    1080             :         int i;
    1081             : 
    1082           0 :         deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
    1083           0 :         num_deps = chunk->length_dw * 4 /
    1084             :                 sizeof(struct drm_amdgpu_cs_chunk_sem);
    1085             : 
    1086           0 :         if (p->post_deps)
    1087             :                 return -EINVAL;
    1088             : 
    1089           0 :         p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
    1090             :                                      GFP_KERNEL);
    1091           0 :         p->num_post_deps = 0;
    1092             : 
    1093           0 :         if (!p->post_deps)
    1094             :                 return -ENOMEM;
    1095             : 
    1096             : 
    1097           0 :         for (i = 0; i < num_deps; ++i) {
    1098           0 :                 p->post_deps[i].syncobj =
    1099           0 :                         drm_syncobj_find(p->filp, deps[i].handle);
    1100           0 :                 if (!p->post_deps[i].syncobj)
    1101             :                         return -EINVAL;
    1102           0 :                 p->post_deps[i].chain = NULL;
    1103           0 :                 p->post_deps[i].point = 0;
    1104           0 :                 p->num_post_deps++;
    1105             :         }
    1106             : 
    1107             :         return 0;
    1108             : }
    1109             : 
    1110             : 
    1111           0 : static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p,
    1112             :                                                       struct amdgpu_cs_chunk *chunk)
    1113             : {
    1114             :         struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
    1115             :         unsigned num_deps;
    1116             :         int i;
    1117             : 
    1118           0 :         syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
    1119           0 :         num_deps = chunk->length_dw * 4 /
    1120             :                 sizeof(struct drm_amdgpu_cs_chunk_syncobj);
    1121             : 
    1122           0 :         if (p->post_deps)
    1123             :                 return -EINVAL;
    1124             : 
    1125           0 :         p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
    1126             :                                      GFP_KERNEL);
    1127           0 :         p->num_post_deps = 0;
    1128             : 
    1129           0 :         if (!p->post_deps)
    1130             :                 return -ENOMEM;
    1131             : 
    1132           0 :         for (i = 0; i < num_deps; ++i) {
    1133           0 :                 struct amdgpu_cs_post_dep *dep = &p->post_deps[i];
    1134             : 
    1135           0 :                 dep->chain = NULL;
    1136           0 :                 if (syncobj_deps[i].point) {
    1137           0 :                         dep->chain = dma_fence_chain_alloc();
    1138           0 :                         if (!dep->chain)
    1139             :                                 return -ENOMEM;
    1140             :                 }
    1141             : 
    1142           0 :                 dep->syncobj = drm_syncobj_find(p->filp,
    1143             :                                                 syncobj_deps[i].handle);
    1144           0 :                 if (!dep->syncobj) {
    1145           0 :                         dma_fence_chain_free(dep->chain);
    1146             :                         return -EINVAL;
    1147             :                 }
    1148           0 :                 dep->point = syncobj_deps[i].point;
    1149           0 :                 p->num_post_deps++;
    1150             :         }
    1151             : 
    1152             :         return 0;
    1153             : }
    1154             : 
    1155           0 : static int amdgpu_cs_dependencies(struct amdgpu_device *adev,
    1156             :                                   struct amdgpu_cs_parser *p)
    1157             : {
    1158             :         int i, r;
    1159             : 
    1160             :         /* TODO: Investigate why we still need the context lock */
    1161           0 :         mutex_unlock(&p->ctx->lock);
    1162             : 
    1163           0 :         for (i = 0; i < p->nchunks; ++i) {
    1164             :                 struct amdgpu_cs_chunk *chunk;
    1165             : 
    1166           0 :                 chunk = &p->chunks[i];
    1167             : 
    1168           0 :                 switch (chunk->chunk_id) {
    1169             :                 case AMDGPU_CHUNK_ID_DEPENDENCIES:
    1170             :                 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
    1171           0 :                         r = amdgpu_cs_process_fence_dep(p, chunk);
    1172           0 :                         if (r)
    1173             :                                 goto out;
    1174             :                         break;
    1175             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
    1176           0 :                         r = amdgpu_cs_process_syncobj_in_dep(p, chunk);
    1177           0 :                         if (r)
    1178             :                                 goto out;
    1179             :                         break;
    1180             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
    1181           0 :                         r = amdgpu_cs_process_syncobj_out_dep(p, chunk);
    1182           0 :                         if (r)
    1183             :                                 goto out;
    1184             :                         break;
    1185             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
    1186           0 :                         r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);
    1187           0 :                         if (r)
    1188             :                                 goto out;
    1189             :                         break;
    1190             :                 case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
    1191           0 :                         r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);
    1192           0 :                         if (r)
    1193             :                                 goto out;
    1194             :                         break;
    1195             :                 }
    1196             :         }
    1197             : 
    1198             : out:
    1199           0 :         mutex_lock(&p->ctx->lock);
    1200           0 :         return r;
    1201             : }
    1202             : 
    1203           0 : static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p)
    1204             : {
    1205             :         int i;
    1206             : 
    1207           0 :         for (i = 0; i < p->num_post_deps; ++i) {
    1208           0 :                 if (p->post_deps[i].chain && p->post_deps[i].point) {
    1209           0 :                         drm_syncobj_add_point(p->post_deps[i].syncobj,
    1210             :                                               p->post_deps[i].chain,
    1211             :                                               p->fence, p->post_deps[i].point);
    1212           0 :                         p->post_deps[i].chain = NULL;
    1213             :                 } else {
    1214           0 :                         drm_syncobj_replace_fence(p->post_deps[i].syncobj,
    1215             :                                                   p->fence);
    1216             :                 }
    1217             :         }
    1218           0 : }
    1219             : 
    1220           0 : static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
    1221             :                             union drm_amdgpu_cs *cs)
    1222             : {
    1223           0 :         struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
    1224           0 :         struct drm_sched_entity *entity = p->entity;
    1225             :         struct amdgpu_bo_list_entry *e;
    1226             :         struct amdgpu_job *job;
    1227             :         uint64_t seq;
    1228             :         int r;
    1229             : 
    1230           0 :         job = p->job;
    1231           0 :         p->job = NULL;
    1232             : 
    1233           0 :         r = drm_sched_job_init(&job->base, entity, &fpriv->vm);
    1234           0 :         if (r)
    1235             :                 goto error_unlock;
    1236             : 
    1237           0 :         drm_sched_job_arm(&job->base);
    1238             : 
    1239             :         /* No memory allocation is allowed while holding the notifier lock.
    1240             :          * The lock is held until amdgpu_cs_submit is finished and fence is
    1241             :          * added to BOs.
    1242             :          */
    1243           0 :         mutex_lock(&p->adev->notifier_lock);
    1244             : 
    1245             :         /* If userptr are invalidated after amdgpu_cs_parser_bos(), return
    1246             :          * -EAGAIN, drmIoctl in libdrm will restart the amdgpu_cs_ioctl.
    1247             :          */
    1248           0 :         amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
    1249           0 :                 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
    1250             : 
    1251           0 :                 r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
    1252             :         }
    1253           0 :         if (r) {
    1254           0 :                 r = -EAGAIN;
    1255             :                 goto error_abort;
    1256             :         }
    1257             : 
    1258           0 :         p->fence = dma_fence_get(&job->base.s_fence->finished);
    1259             : 
    1260           0 :         seq = amdgpu_ctx_add_fence(p->ctx, entity, p->fence);
    1261           0 :         amdgpu_cs_post_dependencies(p);
    1262             : 
    1263           0 :         if ((job->preamble_status & AMDGPU_PREAMBLE_IB_PRESENT) &&
    1264           0 :             !p->ctx->preamble_presented) {
    1265           0 :                 job->preamble_status |= AMDGPU_PREAMBLE_IB_PRESENT_FIRST;
    1266           0 :                 p->ctx->preamble_presented = true;
    1267             :         }
    1268             : 
    1269           0 :         cs->out.handle = seq;
    1270           0 :         job->uf_sequence = seq;
    1271             : 
    1272           0 :         amdgpu_job_free_resources(job);
    1273             : 
    1274           0 :         trace_amdgpu_cs_ioctl(job);
    1275           0 :         amdgpu_vm_bo_trace_cs(&fpriv->vm, &p->ticket);
    1276           0 :         drm_sched_entity_push_job(&job->base);
    1277             : 
    1278           0 :         amdgpu_vm_move_to_lru_tail(p->adev, &fpriv->vm);
    1279             : 
    1280             :         /* Make sure all BOs are remembered as writers */
    1281           0 :         amdgpu_bo_list_for_each_entry(e, p->bo_list)
    1282           0 :                 e->tv.num_shared = 0;
    1283             : 
    1284           0 :         ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence);
    1285           0 :         mutex_unlock(&p->adev->notifier_lock);
    1286           0 :         mutex_unlock(&p->bo_list->bo_list_mutex);
    1287             : 
    1288             :         return 0;
    1289             : 
    1290             : error_abort:
    1291           0 :         drm_sched_job_cleanup(&job->base);
    1292           0 :         mutex_unlock(&p->adev->notifier_lock);
    1293             : 
    1294             : error_unlock:
    1295           0 :         amdgpu_job_free(job);
    1296             :         return r;
    1297             : }
    1298             : 
    1299             : static void trace_amdgpu_cs_ibs(struct amdgpu_cs_parser *parser)
    1300             : {
    1301             :         int i;
    1302             : 
    1303             :         if (!trace_amdgpu_cs_enabled())
    1304             :                 return;
    1305             : 
    1306             :         for (i = 0; i < parser->job->num_ibs; i++)
    1307             :                 trace_amdgpu_cs(parser, i);
    1308             : }
    1309             : 
    1310           0 : int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
    1311             : {
    1312           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
    1313           0 :         union drm_amdgpu_cs *cs = data;
    1314           0 :         struct amdgpu_cs_parser parser = {};
    1315           0 :         bool reserved_buffers = false;
    1316             :         int r;
    1317             : 
    1318           0 :         if (amdgpu_ras_intr_triggered())
    1319             :                 return -EHWPOISON;
    1320             : 
    1321           0 :         if (!adev->accel_working)
    1322             :                 return -EBUSY;
    1323             : 
    1324           0 :         parser.adev = adev;
    1325           0 :         parser.filp = filp;
    1326             : 
    1327           0 :         r = amdgpu_cs_parser_init(&parser, data);
    1328           0 :         if (r) {
    1329           0 :                 if (printk_ratelimit())
    1330           0 :                         DRM_ERROR("Failed to initialize parser %d!\n", r);
    1331             :                 goto out;
    1332             :         }
    1333             : 
    1334           0 :         r = amdgpu_cs_ib_fill(adev, &parser);
    1335           0 :         if (r)
    1336             :                 goto out;
    1337             : 
    1338           0 :         r = amdgpu_cs_dependencies(adev, &parser);
    1339           0 :         if (r) {
    1340           0 :                 DRM_ERROR("Failed in the dependencies handling %d!\n", r);
    1341           0 :                 goto out;
    1342             :         }
    1343             : 
    1344           0 :         r = amdgpu_cs_parser_bos(&parser, data);
    1345           0 :         if (r) {
    1346           0 :                 if (r == -ENOMEM)
    1347           0 :                         DRM_ERROR("Not enough memory for command submission!\n");
    1348           0 :                 else if (r != -ERESTARTSYS && r != -EAGAIN)
    1349           0 :                         DRM_ERROR("Failed to process the buffer list %d!\n", r);
    1350             :                 goto out;
    1351             :         }
    1352             : 
    1353           0 :         reserved_buffers = true;
    1354             : 
    1355           0 :         trace_amdgpu_cs_ibs(&parser);
    1356             : 
    1357           0 :         r = amdgpu_cs_vm_handling(&parser);
    1358           0 :         if (r)
    1359             :                 goto out;
    1360             : 
    1361           0 :         r = amdgpu_cs_submit(&parser, cs);
    1362             : 
    1363             : out:
    1364           0 :         amdgpu_cs_parser_fini(&parser, r, reserved_buffers);
    1365             : 
    1366           0 :         return r;
    1367             : }
    1368             : 
    1369             : /**
    1370             :  * amdgpu_cs_wait_ioctl - wait for a command submission to finish
    1371             :  *
    1372             :  * @dev: drm device
    1373             :  * @data: data from userspace
    1374             :  * @filp: file private
    1375             :  *
    1376             :  * Wait for the command submission identified by handle to finish.
    1377             :  */
    1378           0 : int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
    1379             :                          struct drm_file *filp)
    1380             : {
    1381           0 :         union drm_amdgpu_wait_cs *wait = data;
    1382           0 :         unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout);
    1383             :         struct drm_sched_entity *entity;
    1384             :         struct amdgpu_ctx *ctx;
    1385             :         struct dma_fence *fence;
    1386             :         long r;
    1387             : 
    1388           0 :         ctx = amdgpu_ctx_get(filp->driver_priv, wait->in.ctx_id);
    1389           0 :         if (ctx == NULL)
    1390             :                 return -EINVAL;
    1391             : 
    1392           0 :         r = amdgpu_ctx_get_entity(ctx, wait->in.ip_type, wait->in.ip_instance,
    1393             :                                   wait->in.ring, &entity);
    1394           0 :         if (r) {
    1395           0 :                 amdgpu_ctx_put(ctx);
    1396           0 :                 return r;
    1397             :         }
    1398             : 
    1399           0 :         fence = amdgpu_ctx_get_fence(ctx, entity, wait->in.handle);
    1400           0 :         if (IS_ERR(fence))
    1401           0 :                 r = PTR_ERR(fence);
    1402           0 :         else if (fence) {
    1403           0 :                 r = dma_fence_wait_timeout(fence, true, timeout);
    1404           0 :                 if (r > 0 && fence->error)
    1405           0 :                         r = fence->error;
    1406             :                 dma_fence_put(fence);
    1407             :         } else
    1408             :                 r = 1;
    1409             : 
    1410           0 :         amdgpu_ctx_put(ctx);
    1411           0 :         if (r < 0)
    1412           0 :                 return r;
    1413             : 
    1414           0 :         memset(wait, 0, sizeof(*wait));
    1415           0 :         wait->out.status = (r == 0);
    1416             : 
    1417           0 :         return 0;
    1418             : }
    1419             : 
    1420             : /**
    1421             :  * amdgpu_cs_get_fence - helper to get fence from drm_amdgpu_fence
    1422             :  *
    1423             :  * @adev: amdgpu device
    1424             :  * @filp: file private
    1425             :  * @user: drm_amdgpu_fence copied from user space
    1426             :  */
    1427           0 : static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev,
    1428             :                                              struct drm_file *filp,
    1429             :                                              struct drm_amdgpu_fence *user)
    1430             : {
    1431             :         struct drm_sched_entity *entity;
    1432             :         struct amdgpu_ctx *ctx;
    1433             :         struct dma_fence *fence;
    1434             :         int r;
    1435             : 
    1436           0 :         ctx = amdgpu_ctx_get(filp->driver_priv, user->ctx_id);
    1437           0 :         if (ctx == NULL)
    1438             :                 return ERR_PTR(-EINVAL);
    1439             : 
    1440           0 :         r = amdgpu_ctx_get_entity(ctx, user->ip_type, user->ip_instance,
    1441             :                                   user->ring, &entity);
    1442           0 :         if (r) {
    1443           0 :                 amdgpu_ctx_put(ctx);
    1444           0 :                 return ERR_PTR(r);
    1445             :         }
    1446             : 
    1447           0 :         fence = amdgpu_ctx_get_fence(ctx, entity, user->seq_no);
    1448           0 :         amdgpu_ctx_put(ctx);
    1449             : 
    1450             :         return fence;
    1451             : }
    1452             : 
    1453           0 : int amdgpu_cs_fence_to_handle_ioctl(struct drm_device *dev, void *data,
    1454             :                                     struct drm_file *filp)
    1455             : {
    1456           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
    1457           0 :         union drm_amdgpu_fence_to_handle *info = data;
    1458             :         struct dma_fence *fence;
    1459             :         struct drm_syncobj *syncobj;
    1460             :         struct sync_file *sync_file;
    1461             :         int fd, r;
    1462             : 
    1463           0 :         fence = amdgpu_cs_get_fence(adev, filp, &info->in.fence);
    1464           0 :         if (IS_ERR(fence))
    1465           0 :                 return PTR_ERR(fence);
    1466             : 
    1467           0 :         if (!fence)
    1468           0 :                 fence = dma_fence_get_stub();
    1469             : 
    1470           0 :         switch (info->in.what) {
    1471             :         case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ:
    1472           0 :                 r = drm_syncobj_create(&syncobj, 0, fence);
    1473           0 :                 dma_fence_put(fence);
    1474           0 :                 if (r)
    1475             :                         return r;
    1476           0 :                 r = drm_syncobj_get_handle(filp, syncobj, &info->out.handle);
    1477           0 :                 drm_syncobj_put(syncobj);
    1478           0 :                 return r;
    1479             : 
    1480             :         case AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD:
    1481           0 :                 r = drm_syncobj_create(&syncobj, 0, fence);
    1482           0 :                 dma_fence_put(fence);
    1483           0 :                 if (r)
    1484             :                         return r;
    1485           0 :                 r = drm_syncobj_get_fd(syncobj, (int *)&info->out.handle);
    1486           0 :                 drm_syncobj_put(syncobj);
    1487           0 :                 return r;
    1488             : 
    1489             :         case AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD:
    1490           0 :                 fd = get_unused_fd_flags(O_CLOEXEC);
    1491           0 :                 if (fd < 0) {
    1492             :                         dma_fence_put(fence);
    1493             :                         return fd;
    1494             :                 }
    1495             : 
    1496           0 :                 sync_file = sync_file_create(fence);
    1497           0 :                 dma_fence_put(fence);
    1498           0 :                 if (!sync_file) {
    1499           0 :                         put_unused_fd(fd);
    1500           0 :                         return -ENOMEM;
    1501             :                 }
    1502             : 
    1503           0 :                 fd_install(fd, sync_file->file);
    1504           0 :                 info->out.handle = fd;
    1505           0 :                 return 0;
    1506             : 
    1507             :         default:
    1508             :                 dma_fence_put(fence);
    1509             :                 return -EINVAL;
    1510             :         }
    1511             : }
    1512             : 
    1513             : /**
    1514             :  * amdgpu_cs_wait_all_fences - wait on all fences to signal
    1515             :  *
    1516             :  * @adev: amdgpu device
    1517             :  * @filp: file private
    1518             :  * @wait: wait parameters
    1519             :  * @fences: array of drm_amdgpu_fence
    1520             :  */
    1521           0 : static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
    1522             :                                      struct drm_file *filp,
    1523             :                                      union drm_amdgpu_wait_fences *wait,
    1524             :                                      struct drm_amdgpu_fence *fences)
    1525             : {
    1526           0 :         uint32_t fence_count = wait->in.fence_count;
    1527             :         unsigned int i;
    1528           0 :         long r = 1;
    1529             : 
    1530           0 :         for (i = 0; i < fence_count; i++) {
    1531             :                 struct dma_fence *fence;
    1532           0 :                 unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns);
    1533             : 
    1534           0 :                 fence = amdgpu_cs_get_fence(adev, filp, &fences[i]);
    1535           0 :                 if (IS_ERR(fence))
    1536           0 :                         return PTR_ERR(fence);
    1537           0 :                 else if (!fence)
    1538           0 :                         continue;
    1539             : 
    1540           0 :                 r = dma_fence_wait_timeout(fence, true, timeout);
    1541           0 :                 dma_fence_put(fence);
    1542           0 :                 if (r < 0)
    1543           0 :                         return r;
    1544             : 
    1545           0 :                 if (r == 0)
    1546             :                         break;
    1547             : 
    1548           0 :                 if (fence->error)
    1549             :                         return fence->error;
    1550             :         }
    1551             : 
    1552           0 :         memset(wait, 0, sizeof(*wait));
    1553           0 :         wait->out.status = (r > 0);
    1554             : 
    1555             :         return 0;
    1556             : }
    1557             : 
    1558             : /**
    1559             :  * amdgpu_cs_wait_any_fence - wait on any fence to signal
    1560             :  *
    1561             :  * @adev: amdgpu device
    1562             :  * @filp: file private
    1563             :  * @wait: wait parameters
    1564             :  * @fences: array of drm_amdgpu_fence
    1565             :  */
    1566           0 : static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev,
    1567             :                                     struct drm_file *filp,
    1568             :                                     union drm_amdgpu_wait_fences *wait,
    1569             :                                     struct drm_amdgpu_fence *fences)
    1570             : {
    1571           0 :         unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns);
    1572           0 :         uint32_t fence_count = wait->in.fence_count;
    1573           0 :         uint32_t first = ~0;
    1574             :         struct dma_fence **array;
    1575             :         unsigned int i;
    1576             :         long r;
    1577             : 
    1578             :         /* Prepare the fence array */
    1579           0 :         array = kcalloc(fence_count, sizeof(struct dma_fence *), GFP_KERNEL);
    1580             : 
    1581           0 :         if (array == NULL)
    1582             :                 return -ENOMEM;
    1583             : 
    1584           0 :         for (i = 0; i < fence_count; i++) {
    1585             :                 struct dma_fence *fence;
    1586             : 
    1587           0 :                 fence = amdgpu_cs_get_fence(adev, filp, &fences[i]);
    1588           0 :                 if (IS_ERR(fence)) {
    1589           0 :                         r = PTR_ERR(fence);
    1590             :                         goto err_free_fence_array;
    1591           0 :                 } else if (fence) {
    1592           0 :                         array[i] = fence;
    1593             :                 } else { /* NULL, the fence has been already signaled */
    1594           0 :                         r = 1;
    1595           0 :                         first = i;
    1596             :                         goto out;
    1597             :                 }
    1598             :         }
    1599             : 
    1600           0 :         r = dma_fence_wait_any_timeout(array, fence_count, true, timeout,
    1601             :                                        &first);
    1602           0 :         if (r < 0)
    1603             :                 goto err_free_fence_array;
    1604             : 
    1605             : out:
    1606           0 :         memset(wait, 0, sizeof(*wait));
    1607           0 :         wait->out.status = (r > 0);
    1608           0 :         wait->out.first_signaled = first;
    1609             : 
    1610           0 :         if (first < fence_count && array[first])
    1611           0 :                 r = array[first]->error;
    1612             :         else
    1613             :                 r = 0;
    1614             : 
    1615             : err_free_fence_array:
    1616           0 :         for (i = 0; i < fence_count; i++)
    1617           0 :                 dma_fence_put(array[i]);
    1618           0 :         kfree(array);
    1619             : 
    1620           0 :         return r;
    1621             : }
    1622             : 
    1623             : /**
    1624             :  * amdgpu_cs_wait_fences_ioctl - wait for multiple command submissions to finish
    1625             :  *
    1626             :  * @dev: drm device
    1627             :  * @data: data from userspace
    1628             :  * @filp: file private
    1629             :  */
    1630           0 : int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
    1631             :                                 struct drm_file *filp)
    1632             : {
    1633           0 :         struct amdgpu_device *adev = drm_to_adev(dev);
    1634           0 :         union drm_amdgpu_wait_fences *wait = data;
    1635           0 :         uint32_t fence_count = wait->in.fence_count;
    1636             :         struct drm_amdgpu_fence *fences_user;
    1637             :         struct drm_amdgpu_fence *fences;
    1638             :         int r;
    1639             : 
    1640             :         /* Get the fences from userspace */
    1641           0 :         fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence),
    1642             :                         GFP_KERNEL);
    1643           0 :         if (fences == NULL)
    1644             :                 return -ENOMEM;
    1645             : 
    1646           0 :         fences_user = u64_to_user_ptr(wait->in.fences);
    1647           0 :         if (copy_from_user(fences, fences_user,
    1648             :                 sizeof(struct drm_amdgpu_fence) * fence_count)) {
    1649             :                 r = -EFAULT;
    1650             :                 goto err_free_fences;
    1651             :         }
    1652             : 
    1653           0 :         if (wait->in.wait_all)
    1654           0 :                 r = amdgpu_cs_wait_all_fences(adev, filp, wait, fences);
    1655             :         else
    1656           0 :                 r = amdgpu_cs_wait_any_fence(adev, filp, wait, fences);
    1657             : 
    1658             : err_free_fences:
    1659           0 :         kfree(fences);
    1660             : 
    1661           0 :         return r;
    1662             : }
    1663             : 
    1664             : /**
    1665             :  * amdgpu_cs_find_mapping - find bo_va for VM address
    1666             :  *
    1667             :  * @parser: command submission parser context
    1668             :  * @addr: VM address
    1669             :  * @bo: resulting BO of the mapping found
    1670             :  * @map: Placeholder to return found BO mapping
    1671             :  *
    1672             :  * Search the buffer objects in the command submission context for a certain
    1673             :  * virtual memory address. Returns allocation structure when found, NULL
    1674             :  * otherwise.
    1675             :  */
    1676           0 : int amdgpu_cs_find_mapping(struct amdgpu_cs_parser *parser,
    1677             :                            uint64_t addr, struct amdgpu_bo **bo,
    1678             :                            struct amdgpu_bo_va_mapping **map)
    1679             : {
    1680           0 :         struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
    1681           0 :         struct ttm_operation_ctx ctx = { false, false };
    1682           0 :         struct amdgpu_vm *vm = &fpriv->vm;
    1683             :         struct amdgpu_bo_va_mapping *mapping;
    1684             :         int r;
    1685             : 
    1686           0 :         addr /= AMDGPU_GPU_PAGE_SIZE;
    1687             : 
    1688           0 :         mapping = amdgpu_vm_bo_lookup_mapping(vm, addr);
    1689           0 :         if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
    1690             :                 return -EINVAL;
    1691             : 
    1692           0 :         *bo = mapping->bo_va->base.bo;
    1693           0 :         *map = mapping;
    1694             : 
    1695             :         /* Double check that the BO is reserved by this CS */
    1696           0 :         if (dma_resv_locking_ctx((*bo)->tbo.base.resv) != &parser->ticket)
    1697             :                 return -EINVAL;
    1698             : 
    1699           0 :         if (!((*bo)->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) {
    1700           0 :                 (*bo)->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
    1701           0 :                 amdgpu_bo_placement_from_domain(*bo, (*bo)->allowed_domains);
    1702           0 :                 r = ttm_bo_validate(&(*bo)->tbo, &(*bo)->placement, &ctx);
    1703           0 :                 if (r)
    1704             :                         return r;
    1705             :         }
    1706             : 
    1707           0 :         return amdgpu_ttm_alloc_gart(&(*bo)->tbo);
    1708             : }

Generated by: LCOV version 1.14