|
@@ -845,15 +845,60 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,
|
|
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
|
|
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
|
|
struct amdgpu_vm *vm = &fpriv->vm;
|
|
struct amdgpu_vm *vm = &fpriv->vm;
|
|
struct amdgpu_ring *ring = p->job->ring;
|
|
struct amdgpu_ring *ring = p->job->ring;
|
|
- int i, r;
|
|
|
|
|
|
+ int i, j, r;
|
|
|
|
+
|
|
|
|
+ for (i = 0, j = 0; i < p->nchunks && j < p->job->num_ibs; i++) {
|
|
|
|
+
|
|
|
|
+ struct amdgpu_cs_chunk *chunk;
|
|
|
|
+ struct amdgpu_ib *ib;
|
|
|
|
+ struct drm_amdgpu_cs_chunk_ib *chunk_ib;
|
|
|
|
+
|
|
|
|
+ chunk = &p->chunks[i];
|
|
|
|
+ ib = &p->job->ibs[j];
|
|
|
|
+ chunk_ib = (struct drm_amdgpu_cs_chunk_ib *)chunk->kdata;
|
|
|
|
+
|
|
|
|
+ if (chunk->chunk_id != AMDGPU_CHUNK_ID_IB)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if (p->job->ring->funcs->parse_cs) {
|
|
|
|
+ struct amdgpu_bo_va_mapping *m;
|
|
|
|
+ struct amdgpu_bo *aobj = NULL;
|
|
|
|
+ uint64_t offset;
|
|
|
|
+ uint8_t *kptr;
|
|
|
|
+
|
|
|
|
+ r = amdgpu_cs_find_mapping(p, chunk_ib->va_start,
|
|
|
|
+ &aobj, &m);
|
|
|
|
+ if (r) {
|
|
|
|
+ DRM_ERROR("IB va_start is invalid\n");
|
|
|
|
+ return r;
|
|
|
|
+ }
|
|
|
|
|
|
- /* Only for UVD/VCE VM emulation */
|
|
|
|
- if (ring->funcs->parse_cs) {
|
|
|
|
- for (i = 0; i < p->job->num_ibs; i++) {
|
|
|
|
- r = amdgpu_ring_parse_cs(ring, p, i);
|
|
|
|
|
|
+ if ((chunk_ib->va_start + chunk_ib->ib_bytes) >
|
|
|
|
+ (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) {
|
|
|
|
+ DRM_ERROR("IB va_start+ib_bytes is invalid\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* the IB should be reserved at this point */
|
|
|
|
+ r = amdgpu_bo_kmap(aobj, (void **)&kptr);
|
|
|
|
+ if (r) {
|
|
|
|
+ return r;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ offset = m->start * AMDGPU_GPU_PAGE_SIZE;
|
|
|
|
+ kptr += chunk_ib->va_start - offset;
|
|
|
|
+
|
|
|
|
+ memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
|
|
|
|
+ amdgpu_bo_kunmap(aobj);
|
|
|
|
+
|
|
|
|
+ /* Only for UVD/VCE VM emulation */
|
|
|
|
+ r = amdgpu_ring_parse_cs(ring, p, j);
|
|
if (r)
|
|
if (r)
|
|
return r;
|
|
return r;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ j++;
|
|
}
|
|
}
|
|
|
|
|
|
if (p->job->vm) {
|
|
if (p->job->vm) {
|
|
@@ -919,54 +964,18 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
|
|
|
|
|
|
parser->job->ring = ring;
|
|
parser->job->ring = ring;
|
|
|
|
|
|
- if (ring->funcs->parse_cs) {
|
|
|
|
- struct amdgpu_bo_va_mapping *m;
|
|
|
|
- struct amdgpu_bo *aobj = NULL;
|
|
|
|
- uint64_t offset;
|
|
|
|
- uint8_t *kptr;
|
|
|
|
-
|
|
|
|
- r = amdgpu_cs_find_mapping(parser, chunk_ib->va_start,
|
|
|
|
- &aobj, &m);
|
|
|
|
- if (r) {
|
|
|
|
- DRM_ERROR("IB va_start is invalid\n");
|
|
|
|
- return r;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ((chunk_ib->va_start + chunk_ib->ib_bytes) >
|
|
|
|
- (m->last + 1) * AMDGPU_GPU_PAGE_SIZE) {
|
|
|
|
- DRM_ERROR("IB va_start+ib_bytes is invalid\n");
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /* the IB should be reserved at this point */
|
|
|
|
- r = amdgpu_bo_kmap(aobj, (void **)&kptr);
|
|
|
|
- if (r) {
|
|
|
|
- return r;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- offset = m->start * AMDGPU_GPU_PAGE_SIZE;
|
|
|
|
- kptr += chunk_ib->va_start - offset;
|
|
|
|
-
|
|
|
|
- r = amdgpu_ib_get(adev, vm, chunk_ib->ib_bytes, ib);
|
|
|
|
- if (r) {
|
|
|
|
- DRM_ERROR("Failed to get ib !\n");
|
|
|
|
- return r;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- memcpy(ib->ptr, kptr, chunk_ib->ib_bytes);
|
|
|
|
- amdgpu_bo_kunmap(aobj);
|
|
|
|
- } else {
|
|
|
|
- r = amdgpu_ib_get(adev, vm, 0, ib);
|
|
|
|
- if (r) {
|
|
|
|
- DRM_ERROR("Failed to get ib !\n");
|
|
|
|
- return r;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ r = amdgpu_ib_get(adev, vm,
|
|
|
|
+ ring->funcs->parse_cs ? chunk_ib->ib_bytes : 0,
|
|
|
|
+ ib);
|
|
|
|
+ if (r) {
|
|
|
|
+ DRM_ERROR("Failed to get ib !\n");
|
|
|
|
+ return r;
|
|
}
|
|
}
|
|
|
|
|
|
ib->gpu_addr = chunk_ib->va_start;
|
|
ib->gpu_addr = chunk_ib->va_start;
|
|
ib->length_dw = chunk_ib->ib_bytes / 4;
|
|
ib->length_dw = chunk_ib->ib_bytes / 4;
|
|
ib->flags = chunk_ib->flags;
|
|
ib->flags = chunk_ib->flags;
|
|
|
|
+
|
|
j++;
|
|
j++;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1212,6 +1221,10 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ r = amdgpu_cs_ib_fill(adev, &parser);
|
|
|
|
+ if (r)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
r = amdgpu_cs_parser_bos(&parser, data);
|
|
r = amdgpu_cs_parser_bos(&parser, data);
|
|
if (r) {
|
|
if (r) {
|
|
if (r == -ENOMEM)
|
|
if (r == -ENOMEM)
|
|
@@ -1222,9 +1235,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|
}
|
|
}
|
|
|
|
|
|
reserved_buffers = true;
|
|
reserved_buffers = true;
|
|
- r = amdgpu_cs_ib_fill(adev, &parser);
|
|
|
|
- if (r)
|
|
|
|
- goto out;
|
|
|
|
|
|
|
|
r = amdgpu_cs_dependencies(adev, &parser);
|
|
r = amdgpu_cs_dependencies(adev, &parser);
|
|
if (r) {
|
|
if (r) {
|