Merge tag 'drm-fixes-2026-06-13' of https://gitlab.freedesktop.org/drm/kernel
Pull drm fixes from Dave Airlie: "Looks like it's settled down a bit more thankfully. Small changes across the board, amdgpu/xe leading with some colorop changes in the core/amd. Otherwise some misc driver fixes. colorop: - make lut interpolation mutable - track colorop updates correctly amdgpu: - UserQ fix - Userptr fix - MCCS freesync fix - track colorop changes correctly amdkfd: - Fix an event information leak - Events bounds check fix - Trap cleanup fix i915: - Check supported link rates DPCD read - Fix phys BO pread/pwrite with offset xe: - fix oops in suspend/shutdown without display - RAS fixes - Use HW_ERR prefix in log - include all registered queues in TLB invalidation - Fix refcount leak in xe_range_tree in error paths - fix job timeout recovery for unstarted jobs and kernel queues amdxdna: - fix possible leak of mm_struct ivpu: - fix integer truncation vc4: - fix leak in krealloc() error handling virtio: - fix dma_fence ref-count leak" * tag 'drm-fixes-2026-06-13' of https://gitlab.freedesktop.org/drm/kernel: (24 commits) accel/amdxdna: Fix mm_struct reference leak in aie2_populate_range() drm/xe: fix job timeout recovery for unstarted jobs and kernel queues drm/xe: fix refcount leak in xe_range_fence_insert() drm/xe: include all registered queues in TLB invalidation drm/xe/hw_error: Use HW_ERR prefix in log drm/xe/drm_ras: Add per node cleanup action drm/xe/drm_ras: Make counter allocation drm managed drm/xe/display: fix oops in suspend/shutdown without display drm/amd/display: use plane color_mgmt_changed to track colorop changes drm/atomic: track individual colorop updates drm/colorop: make lut(1/3)d_interpolation props correctly behave as mutable drm/colorop: Remove read-only comments from interpolation fields drm/i915/gem: Fix phys BO pread/pwrite with offset drm/vc4: fix krealloc() memory leak drm/virtio: Fix driver removal with disabled KMS drm/i915/edp: Check supported link rates DPCD read accel/ivpu: Fix signed integer truncation in IPC receive drm/virtio: fix dma_fence refcount leak on error in virtio_gpu_dma_fence_wait() drm/amd/display: Consult MCCS FreeSync cap only if requested & supported drm/amdkfd: Unwind debug trap enable on copy_to_user failure ...
This commit is contained in:
commit
4fa048ed72
24 files changed
+229
-121
No files matched your search
@@ -999,6 +999,7 @@ again:
|
|||||||
|
|
||||||
if (ret == -EBUSY) {
|
if (ret == -EBUSY) {
|
||||||
amdxdna_umap_put(mapp);
|
amdxdna_umap_put(mapp);
|
||||||
|
mmput(mm);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1009,11 +1010,13 @@ again:
|
|||||||
if (mmu_interval_read_retry(&mapp->notifier, mapp->range.notifier_seq)) {
|
if (mmu_interval_read_retry(&mapp->notifier, mapp->range.notifier_seq)) {
|
||||||
up_write(&xdna->notifier_lock);
|
up_write(&xdna->notifier_lock);
|
||||||
amdxdna_umap_put(mapp);
|
amdxdna_umap_put(mapp);
|
||||||
|
mmput(mm);
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
mapp->invalid = false;
|
mapp->invalid = false;
|
||||||
up_write(&xdna->notifier_lock);
|
up_write(&xdna->notifier_lock);
|
||||||
amdxdna_umap_put(mapp);
|
amdxdna_umap_put(mapp);
|
||||||
|
mmput(mm);
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
put_mm:
|
put_mm:
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
|
|||||||
if (ipc_buf)
|
if (ipc_buf)
|
||||||
memcpy(ipc_buf, rx_msg->ipc_hdr, sizeof(*ipc_buf));
|
memcpy(ipc_buf, rx_msg->ipc_hdr, sizeof(*ipc_buf));
|
||||||
if (rx_msg->jsm_msg) {
|
if (rx_msg->jsm_msg) {
|
||||||
u32 size = min_t(int, rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg));
|
u32 size = min(rx_msg->ipc_hdr->data_size, sizeof(*jsm_msg));
|
||||||
|
|
||||||
if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) {
|
if (rx_msg->jsm_msg->result != VPU_JSM_STATUS_SUCCESS) {
|
||||||
ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result);
|
ivpu_err(vdev, "IPC resp result error: %d\n", rx_msg->jsm_msg->result);
|
||||||
|
|||||||
@@ -1277,6 +1277,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
|||||||
{
|
{
|
||||||
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
|
struct amdgpu_fpriv *fpriv = p->filp->driver_priv;
|
||||||
struct amdgpu_job *leader = p->gang_leader;
|
struct amdgpu_job *leader = p->gang_leader;
|
||||||
|
struct amdgpu_vm *vm = &fpriv->vm;
|
||||||
struct amdgpu_bo_list_entry *e;
|
struct amdgpu_bo_list_entry *e;
|
||||||
struct drm_gem_object *gobj;
|
struct drm_gem_object *gobj;
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
@@ -1322,7 +1323,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
|
|||||||
amdgpu_hmm_range_free(e->range);
|
amdgpu_hmm_range_free(e->range);
|
||||||
e->range = NULL;
|
e->range = NULL;
|
||||||
}
|
}
|
||||||
if (r) {
|
|
||||||
|
if (r || !list_empty(&vm->invalidated)) {
|
||||||
r = -EAGAIN;
|
r = -EAGAIN;
|
||||||
mutex_unlock(&p->adev->notifier_lock);
|
mutex_unlock(&p->adev->notifier_lock);
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -593,7 +593,7 @@ free_syncobj_handles:
|
|||||||
static int
|
static int
|
||||||
amdgpu_userq_wait_count_fences(struct drm_file *filp,
|
amdgpu_userq_wait_count_fences(struct drm_file *filp,
|
||||||
struct drm_amdgpu_userq_wait *wait_info,
|
struct drm_amdgpu_userq_wait *wait_info,
|
||||||
u32 *syncobj_handles, u32 *timeline_points,
|
u32 *syncobj_handles, u64 *timeline_points,
|
||||||
u32 *timeline_handles,
|
u32 *timeline_handles,
|
||||||
struct drm_gem_object **gobj_write,
|
struct drm_gem_object **gobj_write,
|
||||||
struct drm_gem_object **gobj_read)
|
struct drm_gem_object **gobj_read)
|
||||||
@@ -703,7 +703,7 @@ amdgpu_userq_wait_add_fence(struct drm_amdgpu_userq_wait *wait_info,
|
|||||||
static int
|
static int
|
||||||
amdgpu_userq_wait_return_fence_info(struct drm_file *filp,
|
amdgpu_userq_wait_return_fence_info(struct drm_file *filp,
|
||||||
struct drm_amdgpu_userq_wait *wait_info,
|
struct drm_amdgpu_userq_wait *wait_info,
|
||||||
u32 *syncobj_handles, u32 *timeline_points,
|
u32 *syncobj_handles, u64 *timeline_points,
|
||||||
u32 *timeline_handles,
|
u32 *timeline_handles,
|
||||||
struct drm_gem_object **gobj_write,
|
struct drm_gem_object **gobj_write,
|
||||||
struct drm_gem_object **gobj_read)
|
struct drm_gem_object **gobj_read)
|
||||||
@@ -906,7 +906,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||||||
struct drm_file *filp)
|
struct drm_file *filp)
|
||||||
{
|
{
|
||||||
int num_points, num_syncobj, num_read_bo_handles, num_write_bo_handles;
|
int num_points, num_syncobj, num_read_bo_handles, num_write_bo_handles;
|
||||||
u32 *syncobj_handles, *timeline_points, *timeline_handles;
|
u32 *syncobj_handles, *timeline_handles;
|
||||||
|
u64 *timeline_points;
|
||||||
struct drm_amdgpu_userq_wait *wait_info = data;
|
struct drm_amdgpu_userq_wait *wait_info = data;
|
||||||
struct drm_gem_object **gobj_write;
|
struct drm_gem_object **gobj_write;
|
||||||
struct drm_gem_object **gobj_read;
|
struct drm_gem_object **gobj_read;
|
||||||
@@ -935,7 +936,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptr = u64_to_user_ptr(wait_info->syncobj_timeline_points);
|
ptr = u64_to_user_ptr(wait_info->syncobj_timeline_points);
|
||||||
timeline_points = memdup_array_user(ptr, num_points, sizeof(u32));
|
timeline_points = memdup_array_user(ptr, num_points, sizeof(u64));
|
||||||
if (IS_ERR(timeline_points)) {
|
if (IS_ERR(timeline_points)) {
|
||||||
r = PTR_ERR(timeline_points);
|
r = PTR_ERR(timeline_points);
|
||||||
goto free_timeline_handles;
|
goto free_timeline_handles;
|
||||||
|
|||||||
@@ -832,6 +832,12 @@ int kfd_dbg_trap_enable(struct kfd_process *target, uint32_t fd,
|
|||||||
|
|
||||||
if (copy_to_user(runtime_info, (void *)&target->runtime_info, copy_size)) {
|
if (copy_to_user(runtime_info, (void *)&target->runtime_info, copy_size)) {
|
||||||
kfd_dbg_trap_deactivate(target, false, 0);
|
kfd_dbg_trap_deactivate(target, false, 0);
|
||||||
|
fput(target->dbg_ev_file);
|
||||||
|
target->dbg_ev_file = NULL;
|
||||||
|
if (target->debugger_process)
|
||||||
|
atomic_dec(&target->debugger_process->debugged_process_count);
|
||||||
|
target->debug_trap_enabled = false;
|
||||||
|
kfd_unref_process(target);
|
||||||
r = -EFAULT;
|
r = -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -795,6 +795,8 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events)
|
|||||||
struct kfd_event_waiter *event_waiters;
|
struct kfd_event_waiter *event_waiters;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
|
if (num_events > KFD_SIGNAL_EVENT_LIMIT)
|
||||||
|
return NULL;
|
||||||
event_waiters = kzalloc_objs(struct kfd_event_waiter, num_events);
|
event_waiters = kzalloc_objs(struct kfd_event_waiter, num_events);
|
||||||
if (!event_waiters)
|
if (!event_waiters)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -254,8 +254,10 @@ void kfd_smi_event_update_vmfault(struct kfd_node *dev, uint16_t pasid)
|
|||||||
if (task_info) {
|
if (task_info) {
|
||||||
/* Report VM faults from user applications, not retry from kernel */
|
/* Report VM faults from user applications, not retry from kernel */
|
||||||
if (task_info->task.pid)
|
if (task_info->task.pid)
|
||||||
kfd_smi_event_add(0, dev, KFD_SMI_EVENT_VMFAULT, KFD_EVENT_FMT_VMFAULT(
|
kfd_smi_event_add(task_info->tgid, dev,
|
||||||
task_info->task.pid, task_info->task.comm));
|
KFD_SMI_EVENT_VMFAULT,
|
||||||
|
KFD_EVENT_FMT_VMFAULT(task_info->task.pid,
|
||||||
|
task_info->task.comm));
|
||||||
amdgpu_vm_put_task_info(task_info);
|
amdgpu_vm_put_task_info(task_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,7 +358,7 @@ void kfd_smi_event_process(struct kfd_process_device *pdd, bool start)
|
|||||||
task_info = amdgpu_vm_get_task_info_vm(avm);
|
task_info = amdgpu_vm_get_task_info_vm(avm);
|
||||||
|
|
||||||
if (task_info) {
|
if (task_info) {
|
||||||
kfd_smi_event_add(0, pdd->dev,
|
kfd_smi_event_add(task_info->tgid, pdd->dev,
|
||||||
start ? KFD_SMI_EVENT_PROCESS_START :
|
start ? KFD_SMI_EVENT_PROCESS_START :
|
||||||
KFD_SMI_EVENT_PROCESS_END,
|
KFD_SMI_EVENT_PROCESS_END,
|
||||||
KFD_EVENT_FMT_PROCESS(task_info->task.pid,
|
KFD_EVENT_FMT_PROCESS(task_info->task.pid,
|
||||||
|
|||||||
@@ -10083,7 +10083,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
bundle->surface_updates[planes_count].surface = dc_plane;
|
bundle->surface_updates[planes_count].surface = dc_plane;
|
||||||
if (new_pcrtc_state->color_mgmt_changed) {
|
if (new_pcrtc_state->color_mgmt_changed || new_plane_state->color_mgmt_changed) {
|
||||||
bundle->surface_updates[planes_count].gamma = &dc_plane->gamma_correction;
|
bundle->surface_updates[planes_count].gamma = &dc_plane->gamma_correction;
|
||||||
bundle->surface_updates[planes_count].in_transfer_func = &dc_plane->in_transfer_func;
|
bundle->surface_updates[planes_count].in_transfer_func = &dc_plane->in_transfer_func;
|
||||||
bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
|
bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
|
||||||
@@ -11824,6 +11824,10 @@ static bool should_reset_plane(struct drm_atomic_state *state,
|
|||||||
if (new_crtc_state->color_mgmt_changed)
|
if (new_crtc_state->color_mgmt_changed)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Plane color pipeline or its colorop changes. */
|
||||||
|
if (new_plane_state->color_mgmt_changed)
|
||||||
|
return true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On zpos change, planes need to be reordered by removing and re-adding
|
* On zpos change, planes need to be reordered by removing and re-adding
|
||||||
* them one by one to the dc state, in order of descending zpos.
|
* them one by one to the dc state, in order of descending zpos.
|
||||||
@@ -13446,17 +13450,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Handle MCCS */
|
/* Handle MCCS */
|
||||||
if (do_mccs)
|
if (do_mccs) {
|
||||||
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
||||||
|
|
||||||
if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
|
if (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)
|
||||||
as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
|
|
||||||
(!sink->edid_caps.freesync_vcp_code ||
|
|
||||||
(sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
|
|
||||||
freesync_capable = false;
|
freesync_capable = false;
|
||||||
|
|
||||||
if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
|
if (sink->mccs_caps.freesync_supported && freesync_capable)
|
||||||
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
|
||||||
|
}
|
||||||
|
|
||||||
update:
|
update:
|
||||||
if (dm_con_state)
|
if (dm_con_state)
|
||||||
|
|||||||
@@ -830,7 +830,7 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
|
|||||||
case DRM_COLOROP_1D_LUT:
|
case DRM_COLOROP_1D_LUT:
|
||||||
drm_printf(p, "\tsize=%d\n", colorop->size);
|
drm_printf(p, "\tsize=%d\n", colorop->size);
|
||||||
drm_printf(p, "\tinterpolation=%s\n",
|
drm_printf(p, "\tinterpolation=%s\n",
|
||||||
drm_get_colorop_lut1d_interpolation_name(colorop->lut1d_interpolation));
|
drm_get_colorop_lut1d_interpolation_name(state->lut1d_interpolation));
|
||||||
drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
|
drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
|
||||||
break;
|
break;
|
||||||
case DRM_COLOROP_CTM_3X4:
|
case DRM_COLOROP_CTM_3X4:
|
||||||
@@ -842,7 +842,7 @@ static void drm_atomic_colorop_print_state(struct drm_printer *p,
|
|||||||
case DRM_COLOROP_3D_LUT:
|
case DRM_COLOROP_3D_LUT:
|
||||||
drm_printf(p, "\tsize=%d\n", colorop->size);
|
drm_printf(p, "\tsize=%d\n", colorop->size);
|
||||||
drm_printf(p, "\tinterpolation=%s\n",
|
drm_printf(p, "\tinterpolation=%s\n",
|
||||||
drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
|
drm_get_colorop_lut3d_interpolation_name(state->lut3d_interpolation));
|
||||||
drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
|
drm_printf(p, "\tdata blob id=%d\n", state->data ? state->data->base.id : 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -265,13 +265,19 @@ EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
|
|||||||
*
|
*
|
||||||
* Helper function to select the color pipeline on a plane by setting
|
* Helper function to select the color pipeline on a plane by setting
|
||||||
* it to the first drm_colorop element of the pipeline.
|
* it to the first drm_colorop element of the pipeline.
|
||||||
|
*
|
||||||
|
* Return: true if plane color pipeline value changed, false otherwise.
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
|
drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
|
||||||
struct drm_colorop *colorop)
|
struct drm_colorop *colorop)
|
||||||
{
|
{
|
||||||
struct drm_plane *plane = plane_state->plane;
|
struct drm_plane *plane = plane_state->plane;
|
||||||
|
|
||||||
|
/* Color pipeline didn't change */
|
||||||
|
if (plane_state->color_pipeline == colorop)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (colorop)
|
if (colorop)
|
||||||
drm_dbg_atomic(plane->dev,
|
drm_dbg_atomic(plane->dev,
|
||||||
"Set [COLOROP:%d] for [PLANE:%d:%s] state %p\n",
|
"Set [COLOROP:%d] for [PLANE:%d:%s] state %p\n",
|
||||||
@@ -283,6 +289,8 @@ drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
|
|||||||
plane->base.id, plane->name, plane_state);
|
plane->base.id, plane->name, plane_state);
|
||||||
|
|
||||||
plane_state->color_pipeline = colorop;
|
plane_state->color_pipeline = colorop;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(drm_atomic_set_colorop_for_plane);
|
EXPORT_SYMBOL(drm_atomic_set_colorop_for_plane);
|
||||||
|
|
||||||
@@ -604,7 +612,7 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane,
|
|||||||
if (val && !colorop)
|
if (val && !colorop)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
|
|
||||||
drm_atomic_set_colorop_for_plane(state, colorop);
|
state->color_mgmt_changed |= drm_atomic_set_colorop_for_plane(state, colorop);
|
||||||
} else if (property == config->prop_fb_damage_clips) {
|
} else if (property == config->prop_fb_damage_clips) {
|
||||||
ret = drm_property_replace_blob_from_id(dev,
|
ret = drm_property_replace_blob_from_id(dev,
|
||||||
&state->fb_damage_clips,
|
&state->fb_damage_clips,
|
||||||
@@ -713,11 +721,11 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
|
|||||||
static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
|
static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
|
||||||
struct drm_colorop_state *state,
|
struct drm_colorop_state *state,
|
||||||
struct drm_property *property,
|
struct drm_property *property,
|
||||||
uint64_t val)
|
uint64_t val,
|
||||||
|
bool *replaced)
|
||||||
{
|
{
|
||||||
ssize_t elem_size = -1;
|
ssize_t elem_size = -1;
|
||||||
ssize_t size = -1;
|
ssize_t size = -1;
|
||||||
bool replaced = false;
|
|
||||||
|
|
||||||
switch (colorop->type) {
|
switch (colorop->type) {
|
||||||
case DRM_COLOROP_1D_LUT:
|
case DRM_COLOROP_1D_LUT:
|
||||||
@@ -739,28 +747,45 @@ static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
|
|||||||
&state->data,
|
&state->data,
|
||||||
val,
|
val,
|
||||||
-1, size, elem_size,
|
-1, size, elem_size,
|
||||||
&replaced);
|
replaced);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
|
static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
|
||||||
struct drm_colorop_state *state,
|
struct drm_colorop_state *state,
|
||||||
struct drm_file *file_priv,
|
struct drm_file *file_priv,
|
||||||
struct drm_property *property,
|
struct drm_property *property,
|
||||||
uint64_t val)
|
uint64_t val,
|
||||||
|
bool *replaced)
|
||||||
{
|
{
|
||||||
if (property == colorop->bypass_property) {
|
if (property == colorop->bypass_property) {
|
||||||
|
if (state->bypass != val) {
|
||||||
state->bypass = val;
|
state->bypass = val;
|
||||||
|
*replaced = true;
|
||||||
|
}
|
||||||
} else if (property == colorop->lut1d_interpolation_property) {
|
} else if (property == colorop->lut1d_interpolation_property) {
|
||||||
colorop->lut1d_interpolation = val;
|
if (state->lut1d_interpolation != val) {
|
||||||
|
state->lut1d_interpolation = val;
|
||||||
|
*replaced = true;
|
||||||
|
}
|
||||||
} else if (property == colorop->curve_1d_type_property) {
|
} else if (property == colorop->curve_1d_type_property) {
|
||||||
|
if (state->curve_1d_type != val) {
|
||||||
state->curve_1d_type = val;
|
state->curve_1d_type = val;
|
||||||
|
*replaced = true;
|
||||||
|
}
|
||||||
} else if (property == colorop->multiplier_property) {
|
} else if (property == colorop->multiplier_property) {
|
||||||
|
if (state->multiplier != val) {
|
||||||
state->multiplier = val;
|
state->multiplier = val;
|
||||||
|
*replaced = true;
|
||||||
|
}
|
||||||
} else if (property == colorop->lut3d_interpolation_property) {
|
} else if (property == colorop->lut3d_interpolation_property) {
|
||||||
colorop->lut3d_interpolation = val;
|
if (state->lut3d_interpolation != val) {
|
||||||
|
state->lut3d_interpolation = val;
|
||||||
|
*replaced = true;
|
||||||
|
}
|
||||||
} else if (property == colorop->data_property) {
|
} else if (property == colorop->data_property) {
|
||||||
return drm_atomic_color_set_data_property(colorop, state,
|
return drm_atomic_color_set_data_property(colorop, state,
|
||||||
property, val);
|
property, val,
|
||||||
|
replaced);
|
||||||
} else {
|
} else {
|
||||||
drm_dbg_atomic(colorop->dev,
|
drm_dbg_atomic(colorop->dev,
|
||||||
"[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
|
"[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
|
||||||
@@ -782,7 +807,7 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
|
|||||||
else if (property == colorop->bypass_property)
|
else if (property == colorop->bypass_property)
|
||||||
*val = state->bypass;
|
*val = state->bypass;
|
||||||
else if (property == colorop->lut1d_interpolation_property)
|
else if (property == colorop->lut1d_interpolation_property)
|
||||||
*val = colorop->lut1d_interpolation;
|
*val = state->lut1d_interpolation;
|
||||||
else if (property == colorop->curve_1d_type_property)
|
else if (property == colorop->curve_1d_type_property)
|
||||||
*val = state->curve_1d_type;
|
*val = state->curve_1d_type;
|
||||||
else if (property == colorop->multiplier_property)
|
else if (property == colorop->multiplier_property)
|
||||||
@@ -790,7 +815,7 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
|
|||||||
else if (property == colorop->size_property)
|
else if (property == colorop->size_property)
|
||||||
*val = colorop->size;
|
*val = colorop->size;
|
||||||
else if (property == colorop->lut3d_interpolation_property)
|
else if (property == colorop->lut3d_interpolation_property)
|
||||||
*val = colorop->lut3d_interpolation;
|
*val = state->lut3d_interpolation;
|
||||||
else if (property == colorop->data_property)
|
else if (property == colorop->data_property)
|
||||||
*val = (state->data) ? state->data->base.id : 0;
|
*val = (state->data) ? state->data->base.id : 0;
|
||||||
else
|
else
|
||||||
@@ -1275,8 +1300,10 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DRM_MODE_OBJECT_COLOROP: {
|
case DRM_MODE_OBJECT_COLOROP: {
|
||||||
|
struct drm_plane_state *plane_state;
|
||||||
struct drm_colorop *colorop = obj_to_colorop(obj);
|
struct drm_colorop *colorop = obj_to_colorop(obj);
|
||||||
struct drm_colorop_state *colorop_state;
|
struct drm_colorop_state *colorop_state;
|
||||||
|
bool replaced = false;
|
||||||
|
|
||||||
colorop_state = drm_atomic_get_colorop_state(state, colorop);
|
colorop_state = drm_atomic_get_colorop_state(state, colorop);
|
||||||
if (IS_ERR(colorop_state)) {
|
if (IS_ERR(colorop_state)) {
|
||||||
@@ -1285,7 +1312,18 @@ int drm_atomic_set_property(struct drm_atomic_state *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = drm_atomic_colorop_set_property(colorop, colorop_state,
|
ret = drm_atomic_colorop_set_property(colorop, colorop_state,
|
||||||
file_priv, prop, prop_value);
|
file_priv, prop, prop_value,
|
||||||
|
&replaced);
|
||||||
|
if (ret || !replaced)
|
||||||
|
break;
|
||||||
|
|
||||||
|
plane_state = drm_atomic_get_plane_state(state, colorop->plane);
|
||||||
|
if (IS_ERR(plane_state)) {
|
||||||
|
ret = PTR_ERR(plane_state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
plane_state->color_mgmt_changed |= replaced;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -342,7 +342,6 @@ int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_color
|
|||||||
|
|
||||||
colorop->lut1d_interpolation_property = prop;
|
colorop->lut1d_interpolation_property = prop;
|
||||||
drm_object_attach_property(&colorop->base, prop, interpolation);
|
drm_object_attach_property(&colorop->base, prop, interpolation);
|
||||||
colorop->lut1d_interpolation = interpolation;
|
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
ret = drm_colorop_create_data_prop(dev, colorop);
|
ret = drm_colorop_create_data_prop(dev, colorop);
|
||||||
@@ -442,7 +441,6 @@ int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *col
|
|||||||
|
|
||||||
colorop->lut3d_interpolation_property = prop;
|
colorop->lut3d_interpolation_property = prop;
|
||||||
drm_object_attach_property(&colorop->base, prop, interpolation);
|
drm_object_attach_property(&colorop->base, prop, interpolation);
|
||||||
colorop->lut3d_interpolation = interpolation;
|
|
||||||
|
|
||||||
/* data */
|
/* data */
|
||||||
ret = drm_colorop_create_data_prop(dev, colorop);
|
ret = drm_colorop_create_data_prop(dev, colorop);
|
||||||
@@ -521,6 +519,20 @@ static void __drm_colorop_state_reset(struct drm_colorop_state *colorop_state,
|
|||||||
&val);
|
&val);
|
||||||
colorop_state->curve_1d_type = val;
|
colorop_state->curve_1d_type = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (colorop->lut1d_interpolation_property) {
|
||||||
|
if (!drm_object_property_get_default_value(&colorop->base,
|
||||||
|
colorop->lut1d_interpolation_property,
|
||||||
|
&val))
|
||||||
|
colorop_state->lut1d_interpolation = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colorop->lut3d_interpolation_property) {
|
||||||
|
if (!drm_object_property_get_default_value(&colorop->base,
|
||||||
|
colorop->lut3d_interpolation_property,
|
||||||
|
&val))
|
||||||
|
colorop_state->lut3d_interpolation = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4678,10 +4678,17 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
|
|||||||
|
|
||||||
if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
|
if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
|
||||||
__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
|
__le16 sink_rates[DP_MAX_SUPPORTED_RATES];
|
||||||
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
drm_dp_dpcd_read(&intel_dp->aux, DP_SUPPORTED_LINK_RATES,
|
ret = drm_dp_dpcd_read_data(&intel_dp->aux,
|
||||||
|
DP_SUPPORTED_LINK_RATES,
|
||||||
sink_rates, sizeof(sink_rates));
|
sink_rates, sizeof(sink_rates));
|
||||||
|
if (ret < 0) {
|
||||||
|
drm_dbg_kms(display->drm,
|
||||||
|
"Unable to read eDP supported link rates, using default rates\n");
|
||||||
|
memset(sink_rates, 0, sizeof(sink_rates));
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
|
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
|
||||||
int rate;
|
int rate;
|
||||||
|
|||||||
@@ -18,6 +18,17 @@
|
|||||||
#include "i915_gem_tiling.h"
|
#include "i915_gem_tiling.h"
|
||||||
#include "i915_scatterlist.h"
|
#include "i915_scatterlist.h"
|
||||||
|
|
||||||
|
/* Abuse scatterlist to store pointer instead of struct page. */
|
||||||
|
static inline void __set_phys_vaddr(struct scatterlist *sg, void *vaddr)
|
||||||
|
{
|
||||||
|
sg_assign_page(sg, (struct page *)vaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *__get_phys_vaddr(struct scatterlist *sg)
|
||||||
|
{
|
||||||
|
return (void *)sg_page(sg);
|
||||||
|
}
|
||||||
|
|
||||||
static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
|
static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct address_space *mapping = obj->base.filp->f_mapping;
|
struct address_space *mapping = obj->base.filp->f_mapping;
|
||||||
@@ -58,7 +69,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj)
|
|||||||
sg->offset = 0;
|
sg->offset = 0;
|
||||||
sg->length = obj->base.size;
|
sg->length = obj->base.size;
|
||||||
|
|
||||||
sg_assign_page(sg, (struct page *)vaddr);
|
__set_phys_vaddr(sg, vaddr);
|
||||||
sg_dma_address(sg) = dma;
|
sg_dma_address(sg) = dma;
|
||||||
sg_dma_len(sg) = obj->base.size;
|
sg_dma_len(sg) = obj->base.size;
|
||||||
|
|
||||||
@@ -99,7 +110,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
|
|||||||
struct sg_table *pages)
|
struct sg_table *pages)
|
||||||
{
|
{
|
||||||
dma_addr_t dma = sg_dma_address(pages->sgl);
|
dma_addr_t dma = sg_dma_address(pages->sgl);
|
||||||
void *vaddr = sg_page(pages->sgl);
|
void *vaddr = __get_phys_vaddr(pages->sgl);
|
||||||
|
|
||||||
__i915_gem_object_release_shmem(obj, pages, false);
|
__i915_gem_object_release_shmem(obj, pages, false);
|
||||||
|
|
||||||
@@ -139,7 +150,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj,
|
|||||||
int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
|
int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
|
||||||
const struct drm_i915_gem_pwrite *args)
|
const struct drm_i915_gem_pwrite *args)
|
||||||
{
|
{
|
||||||
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
|
void *vaddr = __get_phys_vaddr(obj->mm.pages->sgl) + args->offset;
|
||||||
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
||||||
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
struct drm_i915_private *i915 = to_i915(obj->base.dev);
|
||||||
int err;
|
int err;
|
||||||
@@ -170,7 +181,7 @@ int i915_gem_object_pwrite_phys(struct drm_i915_gem_object *obj,
|
|||||||
int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj,
|
int i915_gem_object_pread_phys(struct drm_i915_gem_object *obj,
|
||||||
const struct drm_i915_gem_pread *args)
|
const struct drm_i915_gem_pread *args)
|
||||||
{
|
{
|
||||||
void *vaddr = sg_page(obj->mm.pages->sgl) + args->offset;
|
void *vaddr = __get_phys_vaddr(obj->mm.pages->sgl) + args->offset;
|
||||||
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
char __user *user_data = u64_to_user_ptr(args->data_ptr);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|||||||
@@ -290,15 +290,16 @@ static bool require_uniform_address_uniform(struct vc4_validated_shader_info *va
|
|||||||
{
|
{
|
||||||
uint32_t o = validated_shader->num_uniform_addr_offsets;
|
uint32_t o = validated_shader->num_uniform_addr_offsets;
|
||||||
uint32_t num_uniforms = validated_shader->uniforms_size / 4;
|
uint32_t num_uniforms = validated_shader->uniforms_size / 4;
|
||||||
|
u32 *offsets;
|
||||||
|
|
||||||
validated_shader->uniform_addr_offsets =
|
offsets = krealloc_array(validated_shader->uniform_addr_offsets,
|
||||||
krealloc(validated_shader->uniform_addr_offsets,
|
o + 1,
|
||||||
(o + 1) *
|
|
||||||
sizeof(*validated_shader->uniform_addr_offsets),
|
sizeof(*validated_shader->uniform_addr_offsets),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!validated_shader->uniform_addr_offsets)
|
if (!offsets)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
validated_shader->uniform_addr_offsets = offsets;
|
||||||
validated_shader->uniform_addr_offsets[o] = num_uniforms;
|
validated_shader->uniform_addr_offsets[o] = num_uniforms;
|
||||||
validated_shader->num_uniform_addr_offsets++;
|
validated_shader->num_uniform_addr_offsets++;
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,10 @@ static void virtio_gpu_remove(struct virtio_device *vdev)
|
|||||||
struct drm_device *dev = vdev->priv;
|
struct drm_device *dev = vdev->priv;
|
||||||
|
|
||||||
drm_dev_unplug(dev);
|
drm_dev_unplug(dev);
|
||||||
|
|
||||||
|
if (drm_core_check_feature(dev, DRIVER_ATOMIC))
|
||||||
drm_atomic_helper_shutdown(dev);
|
drm_atomic_helper_shutdown(dev);
|
||||||
|
|
||||||
virtio_gpu_deinit(dev);
|
virtio_gpu_deinit(dev);
|
||||||
drm_dev_put(dev);
|
drm_dev_put(dev);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,9 +65,11 @@ static int virtio_gpu_dma_fence_wait(struct virtio_gpu_submit *submit,
|
|||||||
|
|
||||||
dma_fence_unwrap_for_each(f, &itr, fence) {
|
dma_fence_unwrap_for_each(f, &itr, fence) {
|
||||||
err = virtio_gpu_do_fence_wait(submit, f);
|
err = virtio_gpu_do_fence_wait(submit, f);
|
||||||
if (err)
|
if (err) {
|
||||||
|
dma_fence_put(itr.chain);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,15 @@ int xe_display_init_early(struct xe_device *xe)
|
|||||||
|
|
||||||
intel_display_driver_early_probe(display);
|
intel_display_driver_early_probe(display);
|
||||||
|
|
||||||
|
intel_display_device_info_runtime_init(display);
|
||||||
|
|
||||||
|
/* Display may have been disabled at runtime init */
|
||||||
|
if (!intel_display_device_present(display)) {
|
||||||
|
xe->info.probe_display = false;
|
||||||
|
unset_display_features(xe);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Early display init.. */
|
/* Early display init.. */
|
||||||
intel_opregion_setup(display);
|
intel_opregion_setup(display);
|
||||||
|
|
||||||
@@ -137,8 +146,6 @@ int xe_display_init_early(struct xe_device *xe)
|
|||||||
|
|
||||||
intel_bw_init_hw(display);
|
intel_bw_init_hw(display);
|
||||||
|
|
||||||
intel_display_device_info_runtime_init(display);
|
|
||||||
|
|
||||||
err = intel_display_driver_probe_noirq(display);
|
err = intel_display_driver_probe_noirq(display);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_opregion;
|
goto err_opregion;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ static struct xe_drm_ras_counter *allocate_and_copy_counters(struct xe_device *x
|
|||||||
struct xe_drm_ras_counter *counter;
|
struct xe_drm_ras_counter *counter;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
counter = kcalloc(DRM_XE_RAS_ERR_COMP_MAX, sizeof(*counter), GFP_KERNEL);
|
counter = drmm_kcalloc(&xe->drm, DRM_XE_RAS_ERR_COMP_MAX, sizeof(*counter), GFP_KERNEL);
|
||||||
if (!counter)
|
if (!counter)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
@@ -100,54 +100,47 @@ static int assign_node_params(struct xe_device *xe, struct drm_ras_node *node,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_node_param(struct xe_drm_ras *ras, const enum drm_xe_ras_error_severity severity)
|
static void cleanup_node_param(struct drm_ras_node *node)
|
||||||
{
|
{
|
||||||
struct drm_ras_node *node = &ras->node[severity];
|
|
||||||
|
|
||||||
kfree(ras->info[severity]);
|
|
||||||
ras->info[severity] = NULL;
|
|
||||||
|
|
||||||
kfree(node->device_name);
|
kfree(node->device_name);
|
||||||
node->device_name = NULL;
|
node->device_name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cleanup_node(struct drm_device *drm, void *node)
|
||||||
|
{
|
||||||
|
drm_ras_node_unregister(node);
|
||||||
|
cleanup_node_param(node);
|
||||||
|
}
|
||||||
|
|
||||||
static int register_nodes(struct xe_device *xe)
|
static int register_nodes(struct xe_device *xe)
|
||||||
{
|
{
|
||||||
struct xe_drm_ras *ras = &xe->ras;
|
struct xe_drm_ras *ras = &xe->ras;
|
||||||
int i;
|
struct drm_ras_node *node;
|
||||||
|
int i, ret;
|
||||||
|
|
||||||
for_each_error_severity(i) {
|
for_each_error_severity(i) {
|
||||||
struct drm_ras_node *node = &ras->node[i];
|
node = &ras->node[i];
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = assign_node_params(xe, node, i);
|
ret = assign_node_params(xe, node, i);
|
||||||
if (ret) {
|
if (ret)
|
||||||
cleanup_node_param(ras, i);
|
goto free_param;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = drm_ras_node_register(node);
|
ret = drm_ras_node_register(node);
|
||||||
if (ret) {
|
if (ret)
|
||||||
cleanup_node_param(ras, i);
|
goto free_param;
|
||||||
return ret;
|
|
||||||
}
|
ret = drmm_add_action_or_reset(&xe->drm, cleanup_node, node);
|
||||||
|
if (ret)
|
||||||
|
goto null_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
static void xe_drm_ras_unregister_nodes(struct drm_device *device, void *arg)
|
free_param:
|
||||||
{
|
cleanup_node_param(node);
|
||||||
struct xe_device *xe = arg;
|
null_info:
|
||||||
struct xe_drm_ras *ras = &xe->ras;
|
ras->info[i] = NULL;
|
||||||
int i;
|
return ret;
|
||||||
|
|
||||||
for_each_error_severity(i) {
|
|
||||||
struct drm_ras_node *node = &ras->node[i];
|
|
||||||
|
|
||||||
drm_ras_node_unregister(node);
|
|
||||||
cleanup_node_param(ras, i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,11 +169,5 @@ int xe_drm_ras_init(struct xe_device *xe)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = drmm_add_action_or_reset(&xe->drm, xe_drm_ras_unregister_nodes, xe);
|
|
||||||
if (err) {
|
|
||||||
drm_err(&xe->drm, "Failed to add action for Xe DRM RAS (%pe)\n", ERR_PTR(err));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -157,6 +157,11 @@ static void set_exec_queue_banned(struct xe_exec_queue *q)
|
|||||||
atomic_or(EXEC_QUEUE_STATE_BANNED, &q->guc->state);
|
atomic_or(EXEC_QUEUE_STATE_BANNED, &q->guc->state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_exec_queue_banned(struct xe_exec_queue *q)
|
||||||
|
{
|
||||||
|
atomic_andnot(EXEC_QUEUE_STATE_BANNED, &q->guc->state);
|
||||||
|
}
|
||||||
|
|
||||||
static bool exec_queue_suspended(struct xe_exec_queue *q)
|
static bool exec_queue_suspended(struct xe_exec_queue *q)
|
||||||
{
|
{
|
||||||
return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_SUSPENDED;
|
return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_SUSPENDED;
|
||||||
@@ -1361,7 +1366,8 @@ static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job)
|
|||||||
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
|
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
|
||||||
q->guc->id);
|
q->guc->id);
|
||||||
|
|
||||||
return xe_sched_invalidate_job(job, 2);
|
/* GuC never scheduled this job - let the caller trigger a GT reset. */
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx_timestamp = lower_32_bits(xe_lrc_timestamp(q->lrc[0]));
|
ctx_timestamp = lower_32_bits(xe_lrc_timestamp(q->lrc[0]));
|
||||||
@@ -1458,6 +1464,21 @@ static void disable_scheduling(struct xe_exec_queue *q, bool immediate)
|
|||||||
G2H_LEN_DW_SCHED_CONTEXT_MODE_SET, 1);
|
G2H_LEN_DW_SCHED_CONTEXT_MODE_SET, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recover via GT reset for a kernel queue, or for a GuC scheduling failure (job
|
||||||
|
* never started) on a queue that was not already killed or banned. An already
|
||||||
|
* banned queue must stay banned, so its unstarted jobs do not clear the ban or
|
||||||
|
* trigger a reset.
|
||||||
|
*/
|
||||||
|
static bool timeout_needs_gt_reset(struct xe_exec_queue *q, struct xe_sched_job *job,
|
||||||
|
bool skip_timeout_check)
|
||||||
|
{
|
||||||
|
if (q->flags & EXEC_QUEUE_FLAG_KERNEL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !skip_timeout_check && !xe_sched_job_started(job);
|
||||||
|
}
|
||||||
|
|
||||||
static enum drm_gpu_sched_stat
|
static enum drm_gpu_sched_stat
|
||||||
guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
|
guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
|
||||||
{
|
{
|
||||||
@@ -1606,20 +1627,20 @@ trigger_reset:
|
|||||||
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
|
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
|
||||||
q->guc->id, q->flags);
|
q->guc->id, q->flags);
|
||||||
|
|
||||||
/*
|
if (!wedged) {
|
||||||
* Kernel jobs should never fail, nor should VM jobs if they do
|
if (timeout_needs_gt_reset(q, job, skip_timeout_check)) {
|
||||||
* somethings has gone wrong and the GT needs a reset
|
|
||||||
*/
|
|
||||||
xe_gt_WARN(q->gt, q->flags & EXEC_QUEUE_FLAG_KERNEL,
|
|
||||||
"Kernel-submitted job timed out\n");
|
|
||||||
xe_gt_WARN(q->gt, q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q),
|
|
||||||
"VM job timed out on non-killed execqueue\n");
|
|
||||||
if (!wedged && (q->flags & EXEC_QUEUE_FLAG_KERNEL ||
|
|
||||||
(q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q)))) {
|
|
||||||
if (!xe_sched_invalidate_job(job, 2)) {
|
if (!xe_sched_invalidate_job(job, 2)) {
|
||||||
|
clear_exec_queue_banned(q);
|
||||||
xe_gt_reset_async(q->gt);
|
xe_gt_reset_async(q->gt);
|
||||||
goto rearm;
|
goto rearm;
|
||||||
}
|
}
|
||||||
|
if (q->flags & EXEC_QUEUE_FLAG_KERNEL) {
|
||||||
|
xe_gt_WARN(q->gt, true, "Kernel-submitted job timed out\n");
|
||||||
|
xe_device_declare_wedged(gt_to_xe(q->gt));
|
||||||
|
}
|
||||||
|
} else if (q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q)) {
|
||||||
|
xe_gt_WARN(q->gt, true, "VM job timed out on non-killed execqueue\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark all outstanding jobs as bad, thus completing them */
|
/* Mark all outstanding jobs as bad, thus completing them */
|
||||||
|
|||||||
@@ -255,9 +255,8 @@ static int send_tlb_inval_ctx_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
|
|||||||
#undef EXEC_QUEUE_COUNT_FULL_THRESHOLD
|
#undef EXEC_QUEUE_COUNT_FULL_THRESHOLD
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Move exec queues to a temporary list to issue invalidations. The exec
|
* Move exec queues to a temporary list to issue invalidations. A
|
||||||
* queue must active and a reference must be taken to prevent concurrent
|
* reference must be taken to prevent concurrent deregistrations.
|
||||||
* deregistrations.
|
|
||||||
*
|
*
|
||||||
* List modification is safe because we hold 'vm->exec_queues.lock' for
|
* List modification is safe because we hold 'vm->exec_queues.lock' for
|
||||||
* reading, which prevents external modifications. Using a per-GT list
|
* reading, which prevents external modifications. Using a per-GT list
|
||||||
@@ -266,7 +265,7 @@ static int send_tlb_inval_ctx_ppgtt(struct xe_tlb_inval *tlb_inval, u32 seqno,
|
|||||||
*/
|
*/
|
||||||
list_for_each_entry_safe(q, next, &vm->exec_queues.list[id],
|
list_for_each_entry_safe(q, next, &vm->exec_queues.list[id],
|
||||||
vm_exec_queue_link) {
|
vm_exec_queue_link) {
|
||||||
if (q->ops->active(q) && xe_exec_queue_get_unless_zero(q)) {
|
if (xe_exec_queue_get_unless_zero(q)) {
|
||||||
last_q = q;
|
last_q = q;
|
||||||
list_move_tail(&q->vm_exec_queue_link, &tlb_inval_list);
|
list_move_tail(&q->vm_exec_queue_link, &tlb_inval_list);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,9 +219,9 @@ static void log_hw_error(struct xe_tile *tile, const char *name,
|
|||||||
struct xe_device *xe = tile_to_xe(tile);
|
struct xe_device *xe = tile_to_xe(tile);
|
||||||
|
|
||||||
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
|
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
|
||||||
drm_warn(&xe->drm, "%s %s detected\n", name, severity_str);
|
drm_warn(&xe->drm, HW_ERR "%s %s detected\n", name, severity_str);
|
||||||
else
|
else
|
||||||
drm_err_ratelimited(&xe->drm, "%s %s detected\n", name, severity_str);
|
drm_err_ratelimited(&xe->drm, HW_ERR "%s %s detected\n", name, severity_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_gt_err(struct xe_tile *tile, const char *name, int i, u32 err,
|
static void log_gt_err(struct xe_tile *tile, const char *name, int i, u32 err,
|
||||||
@@ -231,10 +231,10 @@ static void log_gt_err(struct xe_tile *tile, const char *name, int i, u32 err,
|
|||||||
struct xe_device *xe = tile_to_xe(tile);
|
struct xe_device *xe = tile_to_xe(tile);
|
||||||
|
|
||||||
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
|
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
|
||||||
drm_warn(&xe->drm, "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
|
drm_warn(&xe->drm, HW_ERR "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
|
||||||
name, severity_str, i, err);
|
name, severity_str, i, err);
|
||||||
else
|
else
|
||||||
drm_err_ratelimited(&xe->drm, "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
|
drm_err_ratelimited(&xe->drm, HW_ERR "%s %s detected, ERROR_STAT_GT_VECTOR%d:0x%08x\n",
|
||||||
name, severity_str, i, err);
|
name, severity_str, i, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,9 +251,9 @@ static void log_soc_error(struct xe_tile *tile, const char * const *reg_info,
|
|||||||
|
|
||||||
if (strcmp(name, "Undefined")) {
|
if (strcmp(name, "Undefined")) {
|
||||||
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
|
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
|
||||||
drm_warn(&xe->drm, "%s SOC %s detected", name, severity_str);
|
drm_warn(&xe->drm, HW_ERR "%s SOC %s detected", name, severity_str);
|
||||||
else
|
else
|
||||||
drm_err_ratelimited(&xe->drm, "%s SOC %s detected", name, severity_str);
|
drm_err_ratelimited(&xe->drm, HW_ERR "%s SOC %s detected", name, severity_str);
|
||||||
atomic_inc(&info[index].counter);
|
atomic_inc(&info[index].counter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ int xe_range_fence_insert(struct xe_range_fence_tree *tree,
|
|||||||
} else if (err == 0) {
|
} else if (err == 0) {
|
||||||
xe_range_fence_tree_insert(rfence, &tree->root);
|
xe_range_fence_tree_insert(rfence, &tree->root);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
dma_fence_put(fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
free:
|
free:
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#ifndef DRM_ATOMIC_UAPI_H_
|
#ifndef DRM_ATOMIC_UAPI_H_
|
||||||
#define DRM_ATOMIC_UAPI_H_
|
#define DRM_ATOMIC_UAPI_H_
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
struct drm_crtc_state;
|
struct drm_crtc_state;
|
||||||
struct drm_display_mode;
|
struct drm_display_mode;
|
||||||
struct drm_property_blob;
|
struct drm_property_blob;
|
||||||
@@ -50,7 +52,7 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
|
|||||||
struct drm_crtc *crtc);
|
struct drm_crtc *crtc);
|
||||||
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
|
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
|
||||||
struct drm_framebuffer *fb);
|
struct drm_framebuffer *fb);
|
||||||
void drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
|
bool drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
|
||||||
struct drm_colorop *colorop);
|
struct drm_colorop *colorop);
|
||||||
int __must_check
|
int __must_check
|
||||||
drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
|
drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
|
||||||
|
|||||||
+16
-18
@@ -183,6 +183,20 @@ struct drm_colorop_state {
|
|||||||
*/
|
*/
|
||||||
struct drm_property_blob *data;
|
struct drm_property_blob *data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @lut1d_interpolation:
|
||||||
|
*
|
||||||
|
* Interpolation for DRM_COLOROP_1D_LUT
|
||||||
|
*/
|
||||||
|
enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @lut3d_interpolation:
|
||||||
|
*
|
||||||
|
* Interpolation for DRM_COLOROP_3D_LUT
|
||||||
|
*/
|
||||||
|
enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
|
||||||
|
|
||||||
/** @state: backpointer to global drm_atomic_state */
|
/** @state: backpointer to global drm_atomic_state */
|
||||||
struct drm_atomic_state *state;
|
struct drm_atomic_state *state;
|
||||||
};
|
};
|
||||||
@@ -306,26 +320,10 @@ struct drm_colorop {
|
|||||||
*/
|
*/
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
/**
|
|
||||||
* @lut1d_interpolation:
|
|
||||||
*
|
|
||||||
* Read-only
|
|
||||||
* Interpolation for DRM_COLOROP_1D_LUT
|
|
||||||
*/
|
|
||||||
enum drm_colorop_lut1d_interpolation_type lut1d_interpolation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @lut3d_interpolation:
|
|
||||||
*
|
|
||||||
* Read-only
|
|
||||||
* Interpolation for DRM_COLOROP_3D_LUT
|
|
||||||
*/
|
|
||||||
enum drm_colorop_lut3d_interpolation_type lut3d_interpolation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @lut1d_interpolation_property:
|
* @lut1d_interpolation_property:
|
||||||
*
|
*
|
||||||
* Read-only property for DRM_COLOROP_1D_LUT interpolation
|
* Property for DRM_COLOROP_1D_LUT interpolation
|
||||||
*/
|
*/
|
||||||
struct drm_property *lut1d_interpolation_property;
|
struct drm_property *lut1d_interpolation_property;
|
||||||
|
|
||||||
@@ -353,7 +351,7 @@ struct drm_colorop {
|
|||||||
/**
|
/**
|
||||||
* @lut3d_interpolation_property:
|
* @lut3d_interpolation_property:
|
||||||
*
|
*
|
||||||
* Read-only property for DRM_COLOROP_3D_LUT interpolation
|
* Property for DRM_COLOROP_3D_LUT interpolation
|
||||||
*/
|
*/
|
||||||
struct drm_property *lut3d_interpolation_property;
|
struct drm_property *lut3d_interpolation_property;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user