Re: [Intel-gfx] [PATCH] drm/i915: Don't deballoon unused ggtt drm_mm_node in linux guest
> + Zhi and Zhenyu > > Quoting Xiong Zhang (2018-03-29 13:58:41) > > Four drm_mm_node are used to reserve guest ggtt space, but some of > > them may aren't initialized and used in intel_vgt_balloon(), so these > > unused drm_mm_node couldn't be removed through > drm_mm_remove_node(). > > I'm not sure how this slipped by in previous review, but is there an > explanation why we have; > > static struct _balloon_info_ bl_info; > > ... and are not even initializing it? > > This should definitely find it's way into dev_priv and be properly > initialized. [Zhang, Xiong Y] how about move bl_info into struct i915_virtual_gpu ? so that we could get it through dev_priv->vgpu.bl_info thanks > > Regards, Joonas > > > > > Fixes: ff8f797557c7("drm/i915: return the correct usable aperture size > > under gvt environment") > > Signed-off-by: Xiong Zhang > > --- > > drivers/gpu/drm/i915/i915_vgpu.c | 3 +++ > > 1 file changed, 3 insertions(+) > > > > diff --git a/drivers/gpu/drm/i915/i915_vgpu.c > > b/drivers/gpu/drm/i915/i915_vgpu.c > > index 5fe9f3f..7545686 100644 > > --- a/drivers/gpu/drm/i915/i915_vgpu.c > > +++ b/drivers/gpu/drm/i915/i915_vgpu.c > > @@ -100,6 +100,9 @@ static struct _balloon_info_ bl_info; static void > > vgt_deballoon_space(struct i915_ggtt *ggtt, > > struct drm_mm_node *node) { > > + if (!node->allocated) > > + return; > > + > > DRM_DEBUG_DRIVER("deballoon space: range [0x%llx - > 0x%llx] %llu KiB.\n", > > node->start, > > node->start + node->size, > > -- > > 2.7.4 > > > > ___ > > Intel-gfx mailing list > > Intel-gfx@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx > ___ > intel-gvt-dev mailing list > intel-gvt-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Don't deballoon unused ggtt drm_mm_node in linux guest
On 2018.03.30 07:01:02 +, Zhang, Xiong Y wrote: > > + Zhi and Zhenyu > > > > Quoting Xiong Zhang (2018-03-29 13:58:41) > > > Four drm_mm_node are used to reserve guest ggtt space, but some of > > > them may aren't initialized and used in intel_vgt_balloon(), so these > > > unused drm_mm_node couldn't be removed through > > drm_mm_remove_node(). > > > > I'm not sure how this slipped by in previous review, but is there an > > explanation why we have; > > > > static struct _balloon_info_ bl_info; > > > > ... and are not even initializing it? > > > > This should definitely find it's way into dev_priv and be properly > > initialized. > [Zhang, Xiong Y] how about move bl_info into struct i915_virtual_gpu ? so > that we could get it through dev_priv->vgpu.bl_info > yep, seems fine to me. -- Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 signature.asc Description: PGP signature ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v12 02/17] drm/i915/guc/slpc: Disable host RPS
On platforms with GuC SLPC enabled, we need to ensure Host RPS functions don't update HW RPS state that will be controlled by GuC SLPC then. Host RPS functions are now gated by either USES_GUC_SLPC() or rps->enabled checks. If SLPC is enabled following functions will be bypassed 1. gpu_ips_init 2. intel_enable|disable_rps 3. rps portion of sanitize_gt_powersave gen6_rps_irq_handler, rps_work, gen6_set_rps should not get invoked hence GEM_BUG_ON(USES_GUC_SLPC()) is added in those functions. We continue to use the state setup by intel_init_gt_powersave as i915 will be configuring min/max frequency limits. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 18 -- drivers/gpu/drm/i915/i915_sysfs.c | 5 +++-- drivers/gpu/drm/i915/intel_pm.c | 26 +- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 800230b..5176801 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2599,6 +2599,7 @@ intel_info(const struct drm_i915_private *dev_priv) #define USES_GUC(dev_priv) intel_uc_is_using_guc() #define USES_GUC_SUBMISSION(dev_priv) intel_uc_is_using_guc_submission() #define USES_HUC(dev_priv) intel_uc_is_using_huc() +#define USES_GUC_SLPC(dev_priv)intel_uc_is_using_guc_slpc() #define HAS_RESOURCE_STREAMER(dev_priv) ((dev_priv)->info.has_resource_streamer) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 27aee25..cc7dd85 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1192,6 +1192,8 @@ static void gen6_pm_rps_work(struct work_struct *work) int new_delay, adj, min, max; u32 pm_iir = 0; + GEM_BUG_ON(USES_GUC_SLPC(dev_priv)); + spin_lock_irq(&dev_priv->irq_lock); if (rps->interrupts_enabled) { pm_iir = fetch_and_zero(&rps->pm_iir); @@ -1742,6 +1744,8 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) struct intel_rps *rps = &dev_priv->gt_pm.rps; if (pm_iir & dev_priv->pm_rps_events) { + GEM_BUG_ON(USES_GUC_SLPC(dev_priv)); + spin_lock(&dev_priv->irq_lock); gen6_mask_pm_irq(dev_priv, pm_iir & dev_priv->pm_rps_events); if (rps->interrupts_enabled) { @@ -4256,12 +4260,14 @@ void intel_irq_init(struct drm_i915_private *dev_priv) if (HAS_GUC_SCHED(dev_priv)) dev_priv->pm_guc_events = GEN9_GUC_TO_HOST_INT_EVENT; - /* Let's track the enabled rps events */ - if (IS_VALLEYVIEW(dev_priv)) - /* WaGsvRC0ResidencyMethod:vlv */ - dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; - else - dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; + if (!USES_GUC_SLPC(dev_priv)) { + /* Let's track the enabled rps events */ + if (IS_VALLEYVIEW(dev_priv)) + /* WaGsvRC0ResidencyMethod:vlv */ + dev_priv->pm_rps_events = GEN6_PM_RP_UP_EI_EXPIRED; + else + dev_priv->pm_rps_events = GEN6_PM_RPS_EVENTS; + } rps->pm_intrmsk_mbz = 0; diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index e5e6f6b..c3083fa 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -322,9 +322,10 @@ static ssize_t gt_boost_freq_mhz_store(struct device *kdev, rps->boost_freq = val; boost = atomic_read(&rps->num_waiters); } - mutex_unlock(&dev_priv->pcu_lock); - if (boost) + + if (boost && rps->enabled) schedule_work(&rps->work); + mutex_unlock(&dev_priv->pcu_lock); return count; } diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 19e82aa..51bc147e9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6215,6 +6215,8 @@ static int gen6_set_rps(struct drm_i915_private *dev_priv, u8 val) { struct intel_rps *rps = &dev_priv->gt_pm.rps; + GEM_BUG_ON(USES_GUC_SLPC(dev_priv)); + /* min/max delay may still have been modified so be sure to * write the limits value. */ @@ -6310,6 +6312,9 @@ void gen6_rps_busy(struct drm_i915_private *dev_priv) { struct intel_rps *rps = &dev_priv->gt_pm.rps; + if (USES_GUC_SLPC(dev_priv)) + return; + mutex_lock(&dev_priv->pcu_lock); if (rps->enabled) { u8 freq; @@ -6340,6 +6345,9 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) { struct intel_rps *rps =
[Intel-gfx] [PATCH v12 06/17] drm/i915/guc/slpc: Allocate/initialize/release SLPC shared data
Populate SLPC shared data with required default values for slice count, power source/plan, IA perf MSRs. v1: Update for SLPC interface version 2015.2.4. intel_slpc_active() returns 1 if slpc initialized (Paulo) change default host_os to "Windows" Spelling fixes (Sagar and Nick Hoath). Added WARN for checking if upper 32bits of GTT offset of shared object are zero. (Chris) Updated commit message and moved POWER_PLAN and POWER_SOURCE defn. from later patch. (Akash) Add struct_mutex locking while allocating/releasing slpc shared object. This was caught by CI BAT. Adding SLPC state variable to determine if it is active as it not just dependent on shared data setup. Rebase with guc_allocate_vma related changes. v2: WARN_ON for platform_sku validity and space changes.(David) Checkpatch update. v3: Fixing WARNING in igt@drv_module_reload_basic found in trybot BAT with SLPC Enabled. v4: Updated support for GuC v9. s/slice_total/hweight8(slice_mask)/(Dave). v5: SLPC vma map changes and removed explicit type conversions.(Chris). s/freq_unslice_max|min/unslice__max|min_freq. v6: Commit message update. s/msr_value/val for reuse later. v7: Set default values for tasks and min frequency parameters. Moved init with allocation of data so that post GuC load earlier params persist. v8: Added check for SLPC status during cleanup of shared data. SLPC disabling is asynchronous and should complete within 10us. v9: Enabling Balancer task in SLPC. v10: Rebase. v11: Rebase. Added lock specific to SLPC. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_drv.h | 5 + drivers/gpu/drm/i915/intel_guc_slpc.c | 204 ++ drivers/gpu/drm/i915/intel_guc_slpc.h | 3 + 3 files changed, 212 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5176801..d17e778 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2416,6 +2416,11 @@ intel_info(const struct drm_i915_private *dev_priv) #define IS_ALPHA_SUPPORT(intel_info) ((intel_info)->is_alpha_support) +#define IS_ULX_SKU(dev_priv) (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) +#define IS_ULT_SKU(dev_priv) (IS_SKL_ULT(dev_priv) || \ +IS_KBL_ULT(dev_priv) || \ +IS_CFL_ULT(dev_priv)) + #define SKL_REVID_A0 0x0 #define SKL_REVID_B0 0x1 #define SKL_REVID_C0 0x2 diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index 63f100c..974a3c0 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -4,10 +4,203 @@ * Copyright © 2015-2018 Intel Corporation */ +#include + +#include "i915_drv.h" #include "intel_guc_slpc.h" +static inline struct intel_guc *slpc_to_guc(struct intel_guc_slpc *slpc) +{ + return container_of(slpc, struct intel_guc, slpc); +} + +static unsigned int slpc_get_platform_sku(struct drm_i915_private *dev_priv) +{ + enum slpc_platform_sku platform_sku; + + if (IS_ULX_SKU(dev_priv)) + platform_sku = SLPC_PLATFORM_SKU_ULX; + else if (IS_ULT_SKU(dev_priv)) + platform_sku = SLPC_PLATFORM_SKU_ULT; + else + platform_sku = SLPC_PLATFORM_SKU_DT; + + WARN_ON(platform_sku > 0xFF); + + return platform_sku; +} + +static unsigned int slpc_get_slice_count(struct drm_i915_private *dev_priv) +{ + unsigned int slice_count = 1; + + if (IS_SKYLAKE(dev_priv)) + slice_count = hweight8(INTEL_INFO(dev_priv)->sseu.slice_mask); + + return slice_count; +} + +static void slpc_mem_set_param(struct slpc_shared_data *data, + u32 id, + u32 value) +{ + data->override_params_set_bits[id >> 5] |= (1 << (id % 32)); + data->override_params_values[id] = value; +} + +static void slpc_mem_unset_param(struct slpc_shared_data *data, +u32 id) +{ + data->override_params_set_bits[id >> 5] &= (~(1 << (id % 32))); + data->override_params_values[id] = 0; +} + +static int slpc_mem_task_control(struct slpc_shared_data *data, +u64 val, u32 enable_id, u32 disable_id) +{ + int ret = 0; + + if (val == SLPC_PARAM_TASK_DEFAULT) { + /* set default */ + slpc_mem_unset_param(data, enable_id); + slpc_mem_unset_param(data, disable_id); + } else if (val == SLPC_PARAM_TASK_ENABLED) { + /* set enable */ + slpc_mem_set_param(data, enable_id, 1); + slpc_mem_unset_param(data, disable_id); + } else if (val == SLPC_PARAM_TASK_DISABLED) { +
[Intel-gfx] [PATCH v12 04/17] drm/i915/guc/slpc: Enable SLPC in GuC load control params
From: Tom O'Rourke If SLPC is to enabled, then set GUC_CTL_ENABLE_SLPC flag in GuC control param GUC_CTL_FEATURE word during GuC load. This is required for early SLPC init in GuC init path. SLPC gets enabled fully on sending this flag during GuC load and on doing SLPC reset through Host to GuC action. v1: Use intel_slpc_enabled() (Paulo) v2-v4: Rebase. v5: Changed intel_slpc_enabled() to i915.enable_slpc. (Sagar) v6: Changed i915.enable_slpc to intel_slpc_enabled(). (Sagar) v7: Rebase. v8: Rebase. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc.c b/drivers/gpu/drm/i915/intel_guc.c index a00a59a..c8d3ffb 100644 --- a/drivers/gpu/drm/i915/intel_guc.c +++ b/drivers/gpu/drm/i915/intel_guc.c @@ -272,6 +272,9 @@ void intel_guc_init_params(struct intel_guc *guc) params[GUC_CTL_FEATURE] |= GUC_CTL_DISABLE_SCHEDULER | GUC_CTL_VCS2_ENABLED; + if (USES_GUC_SLPC(dev_priv)) + params[GUC_CTL_FEATURE] |= GUC_CTL_ENABLE_SLPC; + params[GUC_CTL_LOG_PARAMS] = guc->log.flags; params[GUC_CTL_DEBUG] = get_log_control_flags(); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v12 00/17] Add support for GuC-based SLPC
SLPC (Single Loop Power Controller) is a replacement for some host-based power management features. The SLPC implementation runs in GuC firmware. This series has been tested with SKL/APL/KBL GuC firmware v9 and v10. The graphics power management features in SLPC are called GTPERF, BALANCER and DCC. 1. GTPERF: Combination of DFPS (Dynamic FPS) and Turbo. DFPS adjusts requested graphics frequency to maintain target framerate. Turbo adjusts requested graphics frequency to maintain target GT busyness. 2. BALANCER: Adjusts balance between power budgets for IA and GT in power limited scenarios. 3. DCC (Duty Cycle Control): Adjusts requested graphics frequency and stalls guc-scheduler to maintain actual graphics frequency in efficient range. This series activates GTPERF Turbo and BALANCER in GuC SLPC. In order to enable CI/PnP testing of SLPC and to avoid frequent rebase, this series should be safe for merge with GuC in disabled state by default currently. v2: Addressed review comments on v1. Removed patch to enable SLPC by default. v3: Addressed WARNING in igt@drv_module_reload_basic flagged by trybot. Added change for sanitizing GT PM during reset. Added separate patch for sysfs interface to know HW requested frequency. v4: Changes to multiple patches. CI BAT is passing. Performance run on SKL GT2 done and shows perf at parity with Host Turbo. For BXT, SLPC improves performance when GuC is enabled compared to Host Turbo. This series keeps only support of 9.18 firmware for readability. If needed, other SLPC interfaces for different GuC version will be added later. v5: This series incorporates feedback from code reviews on earlier series and adds following new changes: 1. More changes for separation of RPS and RC6 handling for Gen9. 2. Tied up SLPC enabling with GuC load/GuC submission sequence. 3. SLPC structures are defined explicitly for event input/output. 4. Definition of SLPC parameter control and task control functions agnostic to the underlying param definitions as they might change with GuC versions and prepared helpers for common tasks. 5. Transition of i915 overrides done through host to guc events to shared data and single reset event. 6. Handling SLPC status post reset through shared memory. 7. Derived helpers for setting frequency limits. 8. Removed sysfs interface to know RPNSWREQ as it is available in debugfs interface i915_frequency_info. 9. Simple igt test to verify SLPC configuration by i915 in various driver scenarios is prepared. v6: This series adds following new changes: 1. Updated intel_guc_send for SLPC to receive output data from GuC. 2. Added task overrides and min frequency overrides in slpc_init. min frequency is set to Rpe. 3. New debugfs interface added to set/unset/read SLPC parameters other than tasks and frequencies. SLPC reset post parameter update added. 4. SLPC parameters persist as part of i915-GuC shared data hence not overriding frequency limits while re-enabling SLPC. 5. Other minor fixes to clear pm_rps_events, clflush the shared data. v7: This series adds following new changes: 1. Reordered patches. SLPC communication interfaces (structures and functions) are pulled into patches earlier in the series. 2. Eliminated dependency on i915.enable_slpc at various functions where rps_enabled is available. 3. s/i915_ggtt_offset/guc_ggtt_offset and sanitization of params in intel_uc_sanitize_options. v8: Activated Balancer. Changed prototype of SLPC functions to accept struct intel_slpc as parameter instead of drm_i915_private. v9: Separated RPS, RC6 and Ring frequency configuration for gen6+. Added TDR specific handling of SLPC reset. Some more improvements for support of function pointers for rps busy, idle, boost functions. This series is based on GuC code restructuring and fixes series at https://patchwork.freedesktop.org/series/30351/. v10-11: Rebase. v12: 1. Rebase. Changed SLPC H2G w.r.t new CTB changes. 2. Removed has_slpc, enable_guc_slpc modparam, GuC version sanitize and platform specific SLPC enabling patches as handling is changed. VIZ-6889, VIZ-6890 Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Beuchat Marc Cc: Wang Zhe1 Cc: Sun Daisy Cc: Oscar Mateo Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee Tested-by: Radoslaw Szwichtenberg Sagar Arun Kamble (12): drm/i915/guc/slpc: Disable host RPS drm/i915/guc/slpc: Lay out SLPC init/enable/disable/fini helpers drm/i915/guc/slpc: Add SLPC communication interfaces drm/i915/guc/slpc: Allocate/initialize/release SLPC shar
[Intel-gfx] [PATCH v12 10/17] drm/i915/guc/slpc: Add parameter set/unset/get, task control/status functions
SLPC behavior can be changed through set of parameters. These parameters can be updated and queried from i915 though Host to GuC SLPC events. This patch adds parameter update events for setting/unsetting/getting params. Setting parameter leads to overridding of default parameter value. Unset leads to restoring of default value by communicating with GuC SLPC through parameter updates in the shared data. i915 can only query/get parameters that it overrides, so getting parameter value is done by only reading from the shared data. SLPC has various tasks, GTPERF, BALANCER and DCC. These can be controlled through pair of GuC SLPC parameters. Enable/disable of these tasks require combined update to both parameters hence new actions are added to control and query the status of tasks. v1: Use host2guc_slpc. Update slcp_param_id enum values for SLPC 2015.2.4 Return void instead of ignored error code (Paulo) v2: Checkpatch update. v3: Rebase. v4: Updated with GuC firmware v9. v5: Updated input structure to host2guc_slpc. Added functions to update only parameters in the SLPC shared memory. This will allow to setup shared data with all parameters and send single event to SLPC take them into effect. Commit message update. (Sagar) v6: Rearranged helpers to use them in slpc_shared_data_init. Added defn. of SLPC_KMD_MAX_PARAM. v7: Added definition of host2guc_slpc with rearrangement of patches. Added task control/status functions. v8: Rebase w.r.t s/intel_guc_send/intel_guc_send_mmio. v9: Created intel_guc_slpc_send_mmio with SLPC specific H2G action send function. Rebase. Defined slpc_statuslist and using the same in intel_guc_slpc_send_mmio. (Michal Wajdeczko) v10: Rebase. Added kernel documentation to the task control functions. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_slpc.c | 173 ++ drivers/gpu/drm/i915/intel_guc_slpc.h | 5 + 2 files changed, 178 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index bdafbaa..011e442 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -404,6 +404,179 @@ static void host2guc_slpc_tdr_reset(struct intel_guc_slpc *slpc) slpc_send(slpc, &data, 5); } +static void host2guc_slpc_set_param(struct intel_guc_slpc *slpc, + u32 id, u32 value) +{ + struct slpc_event_input data = {0}; + + data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_SET, 2); + data.args[0] = id; + data.args[1] = value; + + slpc_send(slpc, &data, 4); +} + +static void host2guc_slpc_unset_param(struct intel_guc_slpc *slpc, + u32 id) +{ + struct slpc_event_input data = {0}; + + data.header.value = SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1); + data.args[0] = id; + + slpc_send(slpc, &data, 3); +} + +static void slpc_set_param(struct intel_guc_slpc *slpc, u32 id, u32 value) +{ + struct slpc_shared_data *data = NULL; + struct page *page; + + GEM_BUG_ON(id >= SLPC_MAX_PARAM); + GEM_BUG_ON(!slpc->vma); + + lockdep_assert_held(&slpc->lock); + + page = i915_vma_first_page(slpc->vma); + data = kmap_atomic(page); + slpc_mem_set_param(data, id, value); + kunmap_atomic(data); + + host2guc_slpc_set_param(slpc, id, value); +} + +static void slpc_unset_param(struct intel_guc_slpc *slpc, u32 id) +{ + struct slpc_shared_data *data = NULL; + struct page *page; + + GEM_BUG_ON(id >= SLPC_MAX_PARAM); + GEM_BUG_ON(!slpc->vma); + + lockdep_assert_held(&slpc->lock); + + page = i915_vma_first_page(slpc->vma); + data = kmap_atomic(page); + slpc_mem_unset_param(data, id); + kunmap_atomic(data); + + host2guc_slpc_unset_param(slpc, id); +} + +static void slpc_get_param(struct intel_guc_slpc *slpc, u32 id, + int *overriding, u32 *value) +{ + struct slpc_shared_data *data = NULL; + struct page *page; + u32 bits; + + GEM_BUG_ON(id >= SLPC_MAX_PARAM); + GEM_BUG_ON(!slpc->vma); + + lockdep_assert_held(&slpc->lock); + + page = i915_vma_first_page(slpc->vma); + data = kmap_atomic(page); + if (overriding) { + bits = data->override_params_set_bits[id >> 5]; + *overriding = (0 != (bits & (1 << (id % 32; + } + if (value) + *value = data->override_params_values[id]; + + kunmap_atomic(data); +} + +/** + * intel_guc_slpc_task_control() - Update status of SLPC task. + * @slpc: pointer to intel_guc_slpc. + * + * This function will update status of task in SLPC shared data. + * Then it invokes SLPC Host to GuC action
[Intel-gfx] [PATCH v12 05/17] drm/i915/guc/slpc: Add SLPC communication interfaces
Communication with SLPC is via Host to GuC interrupt through shared data and parameters. This patch defines the structure of shared data, parameters, data structure to be passed as input and received as output from SLPC. This patch also defines the events to be sent as input and status values output by GuC on processing SLPC events. SLPC shared data has details of SKU type, Slice count, IA Perf MSR values, SLPC state, Power source/plan, SLPC tasks status. Parameters allow overriding task control, frequency range etc. v1: fix whitespace (Sagar) v2-v3: Rebase. v4: Updated with GuC firmware v9. v5: Added definition of input and output data structures for SLPC events. Updated commit message. v6: Removed definition of host2guc_slpc. Will be added in the next patch that uses it. Commit subject update. Rebase. v7: Added definition of SLPC_RESET_FLAG_TDR_OCCURRED to be sent throgh SLPC reset in case of engine reset. Moved all Host/SLPC interfaces from later patches to this patch. Commit message update. v8: Updated value of SLPC_RESET_FLAG_TDR_OCCURRED. v9: Removed struct slpc_param, slpc_paramlist and corresponding defines. Will be added in later patches where they are used. v10: Rebase. Prepared separate header for SLPC firmware interface. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_slpc.h | 2 + drivers/gpu/drm/i915/intel_guc_slpc_fwif.h | 211 + 2 files changed, 213 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_guc_slpc_fwif.h diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h index 66c76fe..81250c0 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/intel_guc_slpc.h @@ -6,6 +6,8 @@ #ifndef _INTEL_GUC_SLPC_H_ #define _INTEL_GUC_SLPC_H_ +#include + struct intel_guc_slpc { }; diff --git a/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h new file mode 100644 index 000..9400af4 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h @@ -0,0 +1,211 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2015-2018 Intel Corporation + */ +#ifndef _INTEL_GUC_SLPC_FWIF_H_ +#define _INTEL_GUC_SLPC_FWIF_H_ + +#include + +enum slpc_status { + SLPC_STATUS_OK = 0, + SLPC_STATUS_ERROR = 1, + SLPC_STATUS_ILLEGAL_COMMAND = 2, + SLPC_STATUS_INVALID_ARGS = 3, + SLPC_STATUS_INVALID_PARAMS = 4, + SLPC_STATUS_INVALID_DATA = 5, + SLPC_STATUS_OUT_OF_RANGE = 6, + SLPC_STATUS_NOT_SUPPORTED = 7, + SLPC_STATUS_NOT_IMPLEMENTED = 8, + SLPC_STATUS_NO_DATA = 9, + SLPC_STATUS_EVENT_NOT_REGISTERED = 10, + SLPC_STATUS_REGISTER_LOCKED = 11, + SLPC_STATUS_TEMPORARILY_UNAVAILABLE = 12, + SLPC_STATUS_VALUE_ALREADY_SET = 13, + SLPC_STATUS_VALUE_ALREADY_UNSET = 14, + SLPC_STATUS_VALUE_NOT_CHANGED = 15, + SLPC_STATUS_MEMIO_ERROR = 16, + SLPC_STATUS_EVENT_QUEUED_REQ_DPC = 17, + SLPC_STATUS_EVENT_QUEUED_NOREQ_DPC = 18, + SLPC_STATUS_NO_EVENT_QUEUED = 19, + SLPC_STATUS_OUT_OF_SPACE = 20, + SLPC_STATUS_TIMEOUT = 21, + SLPC_STATUS_NO_LOCK = 22, + SLPC_STATUS_MAX +}; + +enum slpc_event_id { + SLPC_EVENT_RESET = 0, + SLPC_EVENT_SHUTDOWN = 1, + SLPC_EVENT_PLATFORM_INFO_CHANGE = 2, + SLPC_EVENT_DISPLAY_MODE_CHANGE = 3, + SLPC_EVENT_FLIP_COMPLETE = 4, + SLPC_EVENT_QUERY_TASK_STATE = 5, + SLPC_EVENT_PARAMETER_SET = 6, + SLPC_EVENT_PARAMETER_UNSET = 7, +}; + +enum slpc_param_id { + SLPC_PARAM_TASK_ENABLE_GTPERF = 0, + SLPC_PARAM_TASK_DISABLE_GTPERF = 1, + SLPC_PARAM_TASK_ENABLE_BALANCER = 2, + SLPC_PARAM_TASK_DISABLE_BALANCER = 3, + SLPC_PARAM_TASK_ENABLE_DCC = 4, + SLPC_PARAM_TASK_DISABLE_DCC = 5, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6, + SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7, + SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8, + SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9, + SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10, + SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11, + SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12, + SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13, + SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14, + SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15, + SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16, + SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17, + SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18, + SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19, + SLPC_MAX_PARAM, + SLPC_KMD_MAX_PARAM = 32, +}; + +enum slpc_global_state { + SLPC_GLOBAL_STATE_NOT_RUNNING = 0, + SLPC_GLOBAL_STATE_INITIALIZING = 1, + SLPC_GLOBAL_S
[Intel-gfx] [PATCH v12 03/17] drm/i915/guc/slpc: Lay out SLPC init/enable/disable/fini helpers
SLPC operates based on parameters setup in shared data between i915 and GuC SLPC. This is to be created/initialized in intel_guc_slpc_init. From there onwards i915 can control the SLPC operations by enabling, disabling complete SLPC or changing SLPC parameters. During cleanup, SLPC shared data has to be freed. v1: Return void instead of ignored error code. Replace HAS_SLPC() use with intel_slpc_enabled()/ intel_slpc_active() (Paulo) Enable/disable RC6 in SLPC flows (Sagar) Fix for renaming gen9_disable_rps to gen9_disable_rc6 in "drm/i915/bxt: Explicitly clear the Turbo control register" Defer RC6 and SLPC enabling to intel_gen6_powersave_work. (Sagar) Performance drop with SLPC was happening as ring frequency table was not programmed when SLPC was enabled. This patch programs ring frequency table with SLPC. Initial reset of SLPC is based on kernel parameter as planning to add slpc state in intel_slpc_active. Cleanup is also based on kernel parameter as SLPC gets disabled in disable/suspend.(Sagar) v2: Usage of INTEL_GEN instead of INTEL_INFO->gen (David) Checkpatch update. v3: Rebase v4: Removed reset functions to comply with *_gt_powersave routines. (Sagar) v5: Removed intel_slpc_active. Relying on slpc.active for control flows that are based on SLPC active status in GuC. State setup/cleanup needed for SLPC is handled using kernel parameter i915.enable_slpc. Moved SLPC init and enabling to GuC enable path as SLPC in GuC can start doing the setup post GuC init. Commit message update. (Sagar) v6: Rearranged function definitions. v7: Makefile rearrangement. Reducing usage of i915.enable_slpc and relying mostly on rps.rps_enabled to bypass Host RPS flows. Commit message update. v8: Changed parameters for SLPC functions to struct intel_slpc*. v9: Reinstated intel_slpc_active and intel_slpc_enabled as they are more meaningful. v10: Rebase changes due to creation of intel_guc.h. Updates in intel_guc_cleanup w.r.t slpc cleanup. v11: s/intel_slpc/intel_guc_slpc. Adjusted place for slpc struct inside guc struct. (Michal Wajdeczko) Updated comment about intel_slpc_enable as we plan to not defer the SLPC status check on enabling later and will have to wait for SLPC status as part of intel_slpc_enable itself. Prepared guc_slpc_initialized and guc_slpc_enabled to track state of SLPC initialization and enabling. v12: s/guc_slpc_cleanup/guc_slpc_fini. Updated SLPC flows w.r.t uC flows. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/intel_guc.h | 2 ++ drivers/gpu/drm/i915/intel_guc_slpc.c | 25 + drivers/gpu/drm/i915/intel_guc_slpc.h | 17 + drivers/gpu/drm/i915/intel_uc.c | 30 +- 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/intel_guc_slpc.c create mode 100644 drivers/gpu/drm/i915/intel_guc_slpc.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 0c79c19..499cb89 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -90,6 +90,7 @@ i915-y += intel_uc.o \ intel_guc_ct.o \ intel_guc_fw.o \ intel_guc_log.o \ + intel_guc_slpc.o \ intel_guc_submission.o \ intel_huc.o \ intel_huc_fw.o diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index f1265e1..2d2451a 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -31,6 +31,7 @@ #include "intel_guc_ct.h" #include "intel_guc_log.h" #include "intel_guc_reg.h" +#include "intel_guc_slpc.h" #include "intel_uc_fw.h" #include "i915_vma.h" @@ -48,6 +49,7 @@ struct intel_guc { struct intel_uc_fw fw; struct intel_guc_log log; struct intel_guc_ct ct; + struct intel_guc_slpc slpc; /* Offset where Non-WOPCM memory starts. */ u32 ggtt_pin_bias; diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c new file mode 100644 index 000..63f100c --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -0,0 +1,25 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2015-2018 Intel Corporation + */ + +#include "intel_guc_slpc.h" + +int intel_guc_slpc_init(struct intel_guc_slpc *slpc) +{ + return 0; +} + +int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) +{ + return 0; +} + +void intel_guc_slpc_disable(struct intel_guc_slpc *slpc) +{ +} + +void intel_guc_slpc_fini(struct intel_guc_slpc *slpc) +{ +} diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h new file mode 100644 index 000..66c76f
[Intel-gfx] [PATCH v12 07/17] drm/i915/guc/slpc: Send RESET event to restart/enable SLPC tasks
Host to GuC actions for SLPC receive additional data as output through scratch registers currently. intel_guc_send_and_receive handles this. We need to define SLPC specific Host to GuC send action (slpc_send) as wrapper on top of it to process the SLPC status that is received in SOFT_SCRATCH(1). Send host2guc SLPC reset event to GuC post GuC load for enabling SLPC. Post this, i915 can ascertain if SLPC has started running successfully through shared data. This check is done by waiting for maximum 5ms. SLPC reset event also needs to be sent when parameters in shared data are updated. v1: Extract host2guc_slpc to handle slpc status code and style changes. (Paulo). Removed WARN_ON for checking msb of gtt address of shared gem obj. (Chris). host2guc_action to i915_guc_action change.(Sagar) Updating SLPC enabled status. (Sagar) v2: Commit message update. (David) v3: Rebase. v4: Added DRM_INFO message when SLPC is enabled. v5: Updated patch as host2guc_slpc is moved to earlier patch. SLPC activation status message put after checking the state from shared data during intel_init_gt_powersave. v6: Added definition of host2guc_slpc and clflush the shared data only for required size. Setting state to NOT_RUNNING before sending RESET event. Output data for SLPC actions is to be retrieved during intel_guc_send with lock protection so created wrapper __intel_guc_send that outputs GuC output data if needed. Clearing pm_rps_events on confirming SLPC RUNNING status so that even if host touches any of the PM registers by mistake it should not have any effect. (Sagar) v7: Added save/restore_default_rps as Uncore sanitize will clear the RP_CONTROL setup by BIOS. s/i915_ggtt_offset/guc_ggtt_offset. v8: Added support for handling TDR based SLPC reset. Added functions host2guc_slpc_tdr_reset, intel_slpc_reset_prepare and intel_slpc_tdr_reset to handle TDR based SLPC reset. v9: Moved TDR support to later patch. Removed intel_slpc_get_status and waiting for maximum of 5ms for SLPC state to turn RUNNING instead of hiding the latency across uc_init_hw and init_gt_powersave. s/if..else/switch..case in intel_guc_slpc_get_state_str. Removed SLPC sanitization from init_gt_powersave. (Michal Wajdeczko) v10: Rebase. v11: Rebase. Created slpc_send func as wrapper on guc_send_and_receive. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_slpc.c | 239 ++ 1 file changed, 239 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index 974a3c0..bc2c717 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -163,6 +163,211 @@ static void slpc_shared_data_init(struct intel_guc_slpc *slpc) kunmap_atomic(data); } +static const char *slpc_status_stringify(int status) +{ + const char *str = NULL; + + switch(status) { + case SLPC_STATUS_OK: + str = "Ok"; + break; + case SLPC_STATUS_ERROR: + str = "Error"; + break; + case SLPC_STATUS_ILLEGAL_COMMAND: + str = "Illegal command"; + break; + case SLPC_STATUS_INVALID_ARGS: + str = "Invalid args"; + break; + case SLPC_STATUS_INVALID_PARAMS: + str = "Invalid params"; + break; + case SLPC_STATUS_INVALID_DATA: + str = "Invalid data"; + break; + case SLPC_STATUS_OUT_OF_RANGE: + str = "Out of range"; + break; + case SLPC_STATUS_NOT_SUPPORTED: + str = "Not supported"; + break; + case SLPC_STATUS_NOT_IMPLEMENTED: + str = "Not implemented"; + break; + case SLPC_STATUS_NO_DATA: + str = "No data"; + break; + case SLPC_STATUS_EVENT_NOT_REGISTERED: + str = "Event not registered"; + break; + case SLPC_STATUS_REGISTER_LOCKED: + str = "Register locked"; + break; + case SLPC_STATUS_TEMPORARILY_UNAVAILABLE: + str = "Temporarily unavailable"; + break; + case SLPC_STATUS_VALUE_ALREADY_SET: + str = "Value already set"; + break; + case SLPC_STATUS_VALUE_ALREADY_UNSET: + str = "Value already unset"; + break; + case SLPC_STATUS_VALUE_NOT_CHANGED: + str = "Value not changed"; + break; + case SLPC_STATUS_MEMIO_ERROR: + str = "MMIO error"; + break; + case SLPC_STATUS_EVENT_QUEUED_REQ_DPC: + str = "Event queued, DPC requested"; + break; + cas
[Intel-gfx] [PATCH v12 08/17] drm/i915/guc/slpc: Send SHUTDOWN event to stop SLPC tasks
From: Tom O'Rourke Send SLPC shutdown event during uc_fini_hw or prior to enabling SLPC done while communicating updated parameters in shared data. v1: Return void instead of ignored error code (Paulo). Removed WARN_ON for checking msb of gtt address of shared gem obj. (Chris) Added SLPC state update during disable, suspend and reset. Changed semantics of reset. It is supposed to just disable. (Sagar) v2-v4: Rebase. v5: Updated the input data structure. (Sagar) v6: Rebase. v7: s/i915_ggtt_offset/guc_ggtt_offset. v8: Updated the status check post disabling to wait for 20us. (Sagar) v9: Updated the status check wait time to 5ms for safe margin as it is handled similar to reset by SLPC. s/slpc_disabled/slpc_stopped v10: Rebase. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_slpc.c | 38 +++ drivers/gpu/drm/i915/intel_uc.c | 6 +++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index bc2c717..7f75d218 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -368,6 +368,28 @@ static bool slpc_running(struct intel_guc_slpc *slpc) return (data.global_state == SLPC_GLOBAL_STATE_RUNNING); } +static void host2guc_slpc_shutdown(struct intel_guc_slpc *slpc) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + u32 shared_data_gtt_offset = intel_guc_ggtt_offset(guc, slpc->vma); + struct slpc_event_input data = {0}; + + data.header.value = SLPC_EVENT(SLPC_EVENT_SHUTDOWN, 2); + data.args[0] = shared_data_gtt_offset; + data.args[1] = 0; + + slpc_send(slpc, &data, 4); +} + +static bool slpc_stopped(struct intel_guc_slpc *slpc) +{ + struct slpc_shared_data data; + + slpc_read_shared_data(slpc, &data); + + return (data.global_state == SLPC_GLOBAL_STATE_NOT_RUNNING); +} + /** * intel_guc_slpc_init() - Initialize the SLPC shared data structure. * @slpc: pointer to intel_guc_slpc. @@ -448,8 +470,24 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) return 0; } +/** + * intel_guc_slpc_disable() - Stop SLPC tasks. + * @slpc: pointer to intel_guc_slpc. + * + * This function will stop GuC SLPC tasks by sending Host to GuC action. + */ void intel_guc_slpc_disable(struct intel_guc_slpc *slpc) { + mutex_lock(&slpc->lock); + + host2guc_slpc_shutdown(slpc); + + /* Ensure SLPC is not running */ + if (wait_for(slpc_stopped(slpc), 5)) + DRM_ERROR("SLPC not disabled! State = %s\n", + slpc_get_state(slpc)); + + mutex_unlock(&slpc->lock); } /** diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 5bf33c8..ece6687 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -359,6 +359,9 @@ void intel_uc_sanitize(struct drm_i915_private *i915) GEM_BUG_ON(!HAS_GUC(i915)); + if (USES_GUC_SLPC(dev_priv)) + intel_guc_slpc_disable(&guc->slpc); + guc_disable_communication(guc); intel_huc_sanitize(huc); @@ -484,9 +487,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv) if (USES_GUC_SUBMISSION(dev_priv)) intel_guc_submission_disable(guc); - if (USES_GUC_SLPC(dev_priv)) - intel_guc_slpc_disable(&guc->slpc); - guc_disable_communication(guc); } -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v12 01/17] drm/i915/guc/slpc: Add SLPC control to enable_guc modparam
From: Tom O'Rourke GuC is currently being used for submission and HuC authentication. Choices can be configured through enable_guc modparam. GuC SLPC is GT Power and Performance management feature in GuC. Add another option to enable_guc modparam to control SLPC. v1: Add early call to sanitize enable_guc_slpc in intel_guc_ucode_init Remove sanitize enable_guc_slpc call before firmware version check is performed. (ChrisW) Version check is added in next patch and that will be done as part of slpc_enable_sanitize function in the next patch. (Sagar) Updated slpc option sanitize function call for platforms without GuC support. This was caught by CI BAT. v2: Changed parameter to dev_priv for HAS_SLPC macro. (David) Code indentation based on checkpatch. v3: Rebase. v4: Moved sanitization of SLPC option post GuC load. v5: Removed function intel_slpc_enabled. Planning to rely only on kernel parameter. Moved sanitization prior to GuC load to use the parameter during SLPC state setup during to GuC load. (Sagar) v6: Commit message update. Rebase. v7: Moved SLPC option sanitization to intel_uc_sanitize_options. v8: Clearing SLPC option on GuC load failure. Change moved from later patch. (Sagar) v9: s/enable_slpc/enable_guc_slpc. Rebase w.r.t modparam change. v10: Rebase. Separate modparam is not needed now that we maintain all options in single param enable_guc. Suggested-by: Paulo Zanoni Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_params.c | 5 +++-- drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_uc.c| 23 +++ drivers/gpu/drm/i915/intel_uc.h| 6 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 08108ce..40b799b 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -150,9 +150,10 @@ i915_param_named_unsafe(edp_vswing, int, 0400, "2=default swing(400mV))"); i915_param_named_unsafe(enable_guc, int, 0400, - "Enable GuC load for GuC submission and/or HuC load. " + "Enable GuC load for GuC submission and/or HuC load and/or GuC SLPC. " "Required functionality can be selected using bitmask values. " - "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load)"); + "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load, " + "4=GuC SLPC)"); i915_param_named(guc_log_level, int, 0400, "GuC firmware logging level. Requires GuC to be loaded. " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index c963603..2484925 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -32,6 +32,7 @@ struct drm_printer; #define ENABLE_GUC_SUBMISSION BIT(0) #define ENABLE_GUC_LOAD_HUCBIT(1) +#define ENABLE_GUC_SLPCBIT(2) #define I915_PARAMS_FOR_EACH(param) \ param(char *, vbt_firmware, NULL) \ diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 1cffaf7..0e4a97f 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -56,9 +56,15 @@ static int __get_platform_enable_guc(struct drm_i915_private *dev_priv) struct intel_uc_fw *huc_fw = &dev_priv->huc.fw; int enable_guc = 0; - /* Default is to enable GuC/HuC if we know their firmwares */ - if (intel_uc_fw_is_selected(guc_fw)) + /* +* Default is to enable GuC submission/SLPC/HuC if we know their +* firmwares +*/ + if (intel_uc_fw_is_selected(guc_fw)) { enable_guc |= ENABLE_GUC_SUBMISSION; + enable_guc |= ENABLE_GUC_SLPC; + } + if (intel_uc_fw_is_selected(huc_fw)) enable_guc |= ENABLE_GUC_LOAD_HUC; @@ -110,10 +116,11 @@ static void sanitize_options_early(struct drm_i915_private *dev_priv) if (i915_modparams.enable_guc < 0) i915_modparams.enable_guc = __get_platform_enable_guc(dev_priv); - DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n", + DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s slpc:%s)\n", i915_modparams.enable_guc, yesno(intel_uc_is_using_guc_submission()), -yesno(intel_uc_is_using_huc())); +yesno(intel_uc_is_using_huc()), +yesno(intel_uc_is_using_guc_slpc())); /* Verify GuC firmware availability */ if (intel_uc_is_using_guc() && !intel_uc_fw_is_selected(guc_fw)) { @@ -123,6 +130,14 @@ static void sanitize_options_early(struct drm_i915_private *dev_priv)
[Intel-gfx] [PATCH v12 09/17] drm/i915/guc/slpc: Reset SLPC on engine reset with flag TDR_OCCURRED
On engine reset, SLPC needs to be notified for it to clear metrics/stats. This is done by sending GUC_SLPC_EVENT_RESET with a flag GUC_SLPC_RESET_FLAG_TDR_OCCURRED. v2: Full GPU reset in i915 triggers reload of GuC and SLPC reset happens along that path. Hence only handling engine reset. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_irq.c | 3 +++ drivers/gpu/drm/i915/intel_guc_slpc.c | 36 +++ drivers/gpu/drm/i915/intel_guc_slpc.h | 1 + drivers/gpu/drm/i915/intel_uc.c | 5 + drivers/gpu/drm/i915/intel_uc.h | 1 + 5 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index cc7dd85..726391c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3020,6 +3020,9 @@ void i915_handle_error(struct drm_i915_private *dev_priv, wake_up_bit(&dev_priv->gpu_error.flags, I915_RESET_ENGINE + engine->id); } + + if (!engine_mask) + intel_uc_handle_engine_reset(dev_priv); } if (!engine_mask) diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index 7f75d218..bdafbaa 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -390,6 +390,20 @@ static bool slpc_stopped(struct intel_guc_slpc *slpc) return (data.global_state == SLPC_GLOBAL_STATE_NOT_RUNNING); } +static void host2guc_slpc_tdr_reset(struct intel_guc_slpc *slpc) +{ + struct intel_guc *guc = slpc_to_guc(slpc); + u32 shared_data_gtt_offset = intel_guc_ggtt_offset(guc, slpc->vma); + struct slpc_event_input data = {0}; + + data.header.value = SLPC_EVENT(SLPC_EVENT_RESET, 3); + data.args[0] = shared_data_gtt_offset; + data.args[1] = 0; + data.args[2] = SLPC_RESET_FLAG_TDR_OCCURRED; + + slpc_send(slpc, &data, 5); +} + /** * intel_guc_slpc_init() - Initialize the SLPC shared data structure. * @slpc: pointer to intel_guc_slpc. @@ -471,6 +485,28 @@ int intel_guc_slpc_enable(struct intel_guc_slpc *slpc) } /** + * intel_guc_slpc_handle_engine_reset() - Notify SLPC about engine reset. + * @slpc: pointer to intel_guc_slpc. + * + * On engine reset, SLPC needs to be notified for it to clear metrics/stats. + * This function notifies by invoking SLPC_EVENT_RESET with a flag + * SLPC_RESET_FLAG_TDR_OCCURRED. + */ +void intel_guc_slpc_handle_engine_reset(struct intel_guc_slpc *slpc) +{ + mutex_lock(&slpc->lock); + + host2guc_slpc_tdr_reset(slpc); + + /* Check whether SLPC is running */ + if (wait_for(slpc_running(slpc), 5)) + DRM_ERROR("SLPC not enabled! State = %s\n", + slpc_get_state(slpc)); + + mutex_unlock(&slpc->lock); +} + +/** * intel_guc_slpc_disable() - Stop SLPC tasks. * @slpc: pointer to intel_guc_slpc. * diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h index 87dac07..75f0b5d 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/intel_guc_slpc.h @@ -16,6 +16,7 @@ struct intel_guc_slpc { int intel_guc_slpc_init(struct intel_guc_slpc *slpc); int intel_guc_slpc_enable(struct intel_guc_slpc *slpc); +void intel_guc_slpc_handle_engine_reset(struct intel_guc_slpc *slpc); void intel_guc_slpc_disable(struct intel_guc_slpc *slpc); void intel_guc_slpc_fini(struct intel_guc_slpc *slpc); diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index ece6687..c050444 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -475,6 +475,11 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv) return ret; } +void intel_uc_handle_engine_reset(struct drm_i915_private *dev_priv) +{ + intel_guc_slpc_handle_engine_reset(&dev_priv->guc.slpc); +} + void intel_uc_fini_hw(struct drm_i915_private *dev_priv) { struct intel_guc *guc = &dev_priv->guc; diff --git a/drivers/gpu/drm/i915/intel_uc.h b/drivers/gpu/drm/i915/intel_uc.h index 76139d3..1d67ad3 100644 --- a/drivers/gpu/drm/i915/intel_uc.h +++ b/drivers/gpu/drm/i915/intel_uc.h @@ -35,6 +35,7 @@ int intel_uc_init_misc(struct drm_i915_private *dev_priv); void intel_uc_fini_misc(struct drm_i915_private *dev_priv); void intel_uc_sanitize(struct drm_i915_private *dev_priv); int intel_uc_init_hw(struct drm_i915_private *dev_priv); +void intel_uc_handle_engine_reset(struct drm_i915_private *dev_priv); void intel_uc_fini_hw(struct drm_i915_private *dev_priv); int intel_uc_init(struct drm_i915_private *dev_priv); void intel_uc_fini(struct drm_i915_private *dev_priv); -- 2.7.4 ___ Intel-gfx mailing list I
[Intel-gfx] [PATCH v12 13/17] drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing
Input string parsing used in CRC control parameter parsing is generic and can be reused for other debugfs interfaces. We plan to use this in the next patch for SLPC debugfs control. Hence name it as buffer_tokenize instead of tying to display_crc. Also fix the function desciption for CRC control parsing that was misplaced at tokenize function. v2: Moved buffer_tokenize to i915_debugfs.c (Michal Wajdeczko) Signed-off-by: Sagar Arun Kamble Cc: Tomeu Vizoso Cc: Michal Wajdeczko Acked-by: Radoslaw Szwichtenberg --- drivers/gpu/drm/i915/i915_debugfs.c | 31 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_pipe_crc.c | 57 --- 3 files changed, 45 insertions(+), 44 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d646a04..5c1231f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -5158,3 +5158,34 @@ int i915_debugfs_connector_add(struct drm_connector *connector) return 0; } + +int buffer_tokenize(char *buf, char *words[], int max_words) +{ + int n_words = 0; + + while (*buf) { + char *end; + + /* skip leading white space */ + buf = skip_spaces(buf); + if (!*buf) + break; /* end of buffer */ + + /* find end of word */ + for (end = buf; *end && !isspace(*end); end++) + ; + + if (n_words == max_words) { + DRM_DEBUG_DRIVER("too many words, allowed <= %d\n", +max_words); + return -EINVAL; /* ran out of words[] before bytes */ + } + + if (*end) + *end++ = '\0'; + words[n_words++] = buf; + buf = end; + } + + return n_words; +} diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d17e778..7473d34 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3326,6 +3326,7 @@ u32 i915_gem_fence_alignment(struct drm_i915_private *dev_priv, u32 size, int i915_debugfs_register(struct drm_i915_private *dev_priv); int i915_debugfs_connector_add(struct drm_connector *connector); void intel_display_crc_init(struct drm_i915_private *dev_priv); +int buffer_tokenize(char *buf, char *words[], int max_words); #else static inline int i915_debugfs_register(struct drm_i915_private *dev_priv) {return 0;} static inline int i915_debugfs_connector_add(struct drm_connector *connector) diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c index 4f367c1..6519526 100644 --- a/drivers/gpu/drm/i915/intel_pipe_crc.c +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c @@ -710,49 +710,6 @@ static int pipe_crc_set_source(struct drm_i915_private *dev_priv, return ret; } -/* - * Parse pipe CRC command strings: - * command: wsp* object wsp+ name wsp+ source wsp* - * object: 'pipe' - * name: (A | B | C) - * source: (none | plane1 | plane2 | pf) - * wsp: (#0x20 | #0x9 | #0xA)+ - * - * eg.: - * "pipe A plane1" -> Start CRC computations on plane1 of pipe A - * "pipe A none"-> Stop CRC - */ -static int display_crc_ctl_tokenize(char *buf, char *words[], int max_words) -{ - int n_words = 0; - - while (*buf) { - char *end; - - /* skip leading white space */ - buf = skip_spaces(buf); - if (!*buf) - break; /* end of buffer */ - - /* find end of word */ - for (end = buf; *end && !isspace(*end); end++) - ; - - if (n_words == max_words) { - DRM_DEBUG_DRIVER("too many words, allowed <= %d\n", -max_words); - return -EINVAL; /* ran out of words[] before bytes */ - } - - if (*end) - *end++ = '\0'; - words[n_words++] = buf; - buf = end; - } - - return n_words; -} - enum intel_pipe_crc_object { PIPE_CRC_OBJECT_PIPE, }; @@ -807,6 +764,18 @@ display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s) return -EINVAL; } +/* + * Parse pipe CRC command strings: + * command: wsp* object wsp+ name wsp+ source wsp* + * object: 'pipe' + * name: (A | B | C) + * source: (none | plane1 | plane2 | pf) + * wsp: (#0x20 | #0x9 | #0xA)+ + * + * eg.: + * "pipe A plane1" -> Start CRC computations on plane1 of pipe A + * "pipe A none"-> Stop CRC + */ static int display_crc_ctl_parse(struct drm_i915_private *dev_priv, char *buf, size_t len) { @@ -817,7 +786,7 @@ static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
[Intel-gfx] [PATCH v12 12/17] drm/i915/guc/slpc: Add enable/disable controls for SLPC tasks
From: Tom O'Rourke Adds debugfs hooks for enabling/disabling each SLPC task. The enable/disable debugfs files are: i915_guc_slpc_gtperf, i915_guc_slpc_balancer, and i915_guc_slpc_dcc. Each of these can take the values: "default", "enabled", or "disabled" v1: update for SLPC v2015.2.4 dfps and turbo merged and renamed "gtperf" ibc split out and renamed "balancer" Avoid magic numbers (Jon Bloomfield) v2-v3: Rebase. v5: Moved slpc_enable_disable_set and slpc_enable_disable_get to intel_slpc.c. s/slpc_enable_disable_get/intel_slpc_task_status and s/slpc_enable_disable_set/intel_slpc_task_control. Prepared separate functions to update the task status only in the SLPC shared memory. Passing dev_priv as parameter. v6: Rebase. s/slpc_param_show|write/slpc_task_param_show|write. Moved functions to intel_slpc.c. RPM Get/Put added before setting parameters and sending RESET event explicitly. (Sagar) v7: Rebase. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 200 1 file changed, 200 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index ff90577..d646a04 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2580,6 +2580,203 @@ static const struct file_operations i915_guc_log_relay_fops = { .release = i915_guc_log_relay_release, }; +static const char *slpc_task_status_stringify(int state) +{ + const char *str = NULL; + + switch (state) { + case SLPC_PARAM_TASK_DEFAULT: + str = "default\n"; + break; + + case SLPC_PARAM_TASK_ENABLED: + str = "enabled\n"; + break; + + case SLPC_PARAM_TASK_DISABLED: + str = "disabled\n"; + break; + + default: + str = "unknown\n"; + break; + } + + return str; +} + +static int slpc_task_status_show(struct seq_file *m, +u32 enable_id, +u32 disable_id) +{ + struct drm_i915_private *dev_priv = m->private; + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + const char *status = NULL; + u64 val; + int ret; + + mutex_lock(&slpc->lock); + ret = intel_guc_slpc_task_status(slpc, &val, enable_id, disable_id); + mutex_unlock(&slpc->lock); + + if (!ret) + status = slpc_task_status_stringify(val); + + seq_printf(m, "%s", status); + + return 0; +} + +static int slpc_task_status_write(struct seq_file *m, + const char __user *ubuf, + size_t len, + u32 enable_id, + u32 disable_id) +{ + struct drm_i915_private *dev_priv = m->private; + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + int ret = 0; + char status[10]; + u64 val; + + if (len >= sizeof(status)) + ret = -EINVAL; + else if (copy_from_user(status, ubuf, len)) + ret = -EFAULT; + else + status[len] = '\0'; + + if (ret) + return ret; + + if (!strncmp(status, "default", 7)) + val = SLPC_PARAM_TASK_DEFAULT; + else if (!strncmp(status, "enabled", 7)) + val = SLPC_PARAM_TASK_ENABLED; + else if (!strncmp(status, "disabled", 8)) + val = SLPC_PARAM_TASK_DISABLED; + else + return -EINVAL; + + mutex_lock(&slpc->lock); + ret = intel_guc_slpc_task_control(slpc, val, enable_id, disable_id); + mutex_unlock(&slpc->lock); + + return ret; +} + +static int slpc_gtperf_show(struct seq_file *m, void *data) +{ + return slpc_task_status_show(m, +SLPC_PARAM_TASK_ENABLE_GTPERF, +SLPC_PARAM_TASK_DISABLE_GTPERF); +} + +static int i915_guc_slpc_gtperf_open(struct inode *inode, struct file *file) +{ + struct drm_i915_private *dev_priv = inode->i_private; + + return single_open(file, slpc_gtperf_show, dev_priv); +} + +static ssize_t i915_guc_slpc_gtperf_write(struct file *file, + const char __user *ubuf, + size_t len, + loff_t *offp) +{ + struct seq_file *m = file->private_data; + int ret = 0; + + ret = slpc_task_status_write(m, ubuf, len, +SLPC_PARAM_TASK_ENABLE_GTPERF, +SLPC_PARAM_TASK_DISABLE_GTPERF); + + return ret ?: len; +} + +const struct file_operations i915_gu
[Intel-gfx] [PATCH v12 14/17] drm/i915/guc/slpc: Add debugfs support to read/write/revert the parameters
Add support to set/read parameters and unset the parameters which will revert them to default SLPC internal values. Explicit SLPC reset is needed on setting/unsetting some of the parameters. This patch adds two debugfs interfaces: 1. i915_guc_slpc_params: List of all parameters that Host can configure. Currently listing id and description of each. 2. i915_guc_slpc_param_ctl: This allows to change the parameters. Syntax is: * Update parameter with id with value : echo "write " > i915_guc_slpc_param_ctl * Read parameter with id echo "read " > i915_guc_slpc_param_ctl cat i915_guc_slpc_param_ctl * Revert parameter with id to default value echo "revert " > i915_guc_slpc_param_ctl. v2: Moved the SLPC interfaces to i915_debugfs.c. Added error handling to the range of parameters and parsing. Making use of intel_guc_slpc_enabled instead of accessing status variable. Optimized token parsing. (Michal Wajdeczko) s/i915_slpc_paramlist/i915_guc_slpc_params and s/i915_slpc_param_ctl/i915_guc_slpc_param_ctl v3: Rebase. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c| 156 + drivers/gpu/drm/i915/intel_guc_slpc.c | 87 drivers/gpu/drm/i915/intel_guc_slpc.h | 18 drivers/gpu/drm/i915/intel_guc_slpc_fwif.h | 23 + 4 files changed, 284 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5c1231f..f90ad52 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2777,6 +2777,160 @@ const struct file_operations i915_guc_slpc_dcc_fops = { .llseek = seq_lseek }; +static int i915_guc_slpc_params_info(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct drm_printer p = drm_seq_file_printer(m); + + if (!USES_GUC_SLPC(dev_priv)) + return -ENODEV; + + intel_guc_slpc_params_print(&dev_priv->guc.slpc, &p); + + return 0; +} + +static int slpc_param_ctl_show(struct seq_file *m, void *data) +{ + struct drm_i915_private *dev_priv = m->private; + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + + if (!USES_GUC_SLPC(dev_priv)) + return -ENODEV; + + if (slpc->debug.param_id >= SLPC_MAX_PARAM) + return -EINVAL; + + BUILD_BUG_ON(ARRAY_SIZE(slpc_params_desc) != SLPC_MAX_PARAM); + + seq_printf(m, "%s=%u, override=%s\n", + slpc_params_desc[slpc->debug.param_id], + slpc->debug.param_value, + yesno(!!slpc->debug.param_override)); + + return 0; +} + +static int slpc_param_ctl_open(struct inode *inode, struct file *file) +{ + return single_open(file, slpc_param_ctl_show, inode->i_private); +} + +/* + * Parse SLPC parameter control strings: (Similar to Pipe CRC handling) + * command: wsp* op wsp+ param id wsp+ [value] wsp* + * op: "read"/"write"/"revert" + * param id: slpc_param_id + * value: u32 value + * wsp: (#0x20 | #0x9 | #0xA)+ + * + * eg.: + * "read 0" -> read SLPC_PARAM_TASK_ENABLE_GTPERF + * "write 7 500" -> set SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to 500MHz + * "revert 7" -> revert SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ to + *default value. + */ +static int slpc_param_ctl_parse(char *buf, size_t len, int *op, + u32 *id, u32 *value) +{ +#define MAX_WORDS 3 + int n_words; + char *words[MAX_WORDS]; + ssize_t ret; + + n_words = buffer_tokenize(buf, words, MAX_WORDS); + if (!(n_words == 3) && !(n_words == 2)) { + DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n", +MAX_WORDS); + return -EINVAL; + } + + if (!strcmp(words[0], "read")) + *op = READ_OP; + else if (!strcmp(words[0], "write")) + *op = WRITE_OP; + else if (!strcmp(words[0], "revert")) + *op = REVERT_OP; + else { + DRM_DEBUG_DRIVER("unknown operation\n"); + return -EINVAL; + } + + ret = kstrtou32(words[1], 0, id); + if (ret) + return ret; + + if (n_words == 3) { + ret = kstrtou32(words[2], 0, value); + if (ret) + return ret; + } + + return (n_words-1); +} + +static ssize_t slpc_param_ctl_write(struct file *file, const char __user *ubuf, +size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct drm_i915_private *dev_priv = m->private; + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + char *tmpbuf; +
[Intel-gfx] [PATCH v12 11/17] drm/i915/guc/slpc: Add support for sysfs min/max frequency control
Update sysfs functions to set SLPC parameters when setting max/min user frequency limits. v1: Update for SLPC 2015.2.4 (params for both slice and unslice). Replace HAS_SLPC with intel_slpc_active() (Paulo) v2-v4: Rebase. v5: Removed typecasting the frequency values to u32. (Chris). Changed intel_slpc_active to guc.slpc.enabled. Carved out SLPC helpers to set min and max frequencies. v6: Rebase. Doing explicit SLPC reset on setting frequency to start sane and covered with RPM get/put. Caching SLPC limits post enabling first. v7: Rebase due to change in the dev_priv->pm.rps structure. v8: Updated returns from gt_min_freq_mhz_store and gt_max_freq_mhz_store and i915_min_freq_set and i915_max_freq_set. v9: Rebase. Debugfs interfaces will be removed hence only updated sysfs. Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_sysfs.c | 52 + drivers/gpu/drm/i915/intel_guc_slpc.c | 86 ++- drivers/gpu/drm/i915/intel_guc_slpc.h | 6 +++ 3 files changed, 133 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index c3083fa..d1b4793 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c @@ -343,10 +343,20 @@ static ssize_t vlv_rpe_freq_mhz_show(struct device *kdev, static ssize_t gt_max_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + u32 freq; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(dev_priv, - dev_priv->gt_pm.rps.max_freq_softlimit)); + if (USES_GUC_SLPC(dev_priv)) { + mutex_lock(&slpc->lock); + freq = dev_priv->guc.slpc.max_unslice_freq; + mutex_unlock(&slpc->lock); + } else { + mutex_lock(&dev_priv->pcu_lock); + freq = dev_priv->gt_pm.rps.max_freq_softlimit; + mutex_lock(&dev_priv->pcu_lock); + } + + return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, freq)); } static ssize_t gt_max_freq_mhz_store(struct device *kdev, @@ -362,12 +372,17 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, if (ret) return ret; + val = intel_freq_opcode(dev_priv, val); + + if (USES_GUC_SLPC(dev_priv)) { + ret = intel_guc_slpc_max_freq_set(&dev_priv->guc.slpc, val); + goto out; + } + intel_runtime_pm_get(dev_priv); mutex_lock(&dev_priv->pcu_lock); - val = intel_freq_opcode(dev_priv, val); - if (val < rps->min_freq || val > rps->max_freq || val < rps->min_freq_softlimit) { @@ -395,16 +410,27 @@ static ssize_t gt_max_freq_mhz_store(struct device *kdev, intel_runtime_pm_put(dev_priv); +out: return ret ?: count; } static ssize_t gt_min_freq_mhz_show(struct device *kdev, struct device_attribute *attr, char *buf) { struct drm_i915_private *dev_priv = kdev_minor_to_i915(kdev); + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + u32 freq; - return snprintf(buf, PAGE_SIZE, "%d\n", - intel_gpu_freq(dev_priv, - dev_priv->gt_pm.rps.min_freq_softlimit)); + if (USES_GUC_SLPC(dev_priv)) { + mutex_lock(&slpc->lock); + freq = dev_priv->guc.slpc.min_unslice_freq; + mutex_unlock(&slpc->lock); + } else { + mutex_lock(&dev_priv->pcu_lock); + freq = dev_priv->gt_pm.rps.min_freq_softlimit; + mutex_lock(&dev_priv->pcu_lock); + } + + return snprintf(buf, PAGE_SIZE, "%d\n", intel_gpu_freq(dev_priv, freq)); } static ssize_t gt_min_freq_mhz_store(struct device *kdev, @@ -420,12 +446,17 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, if (ret) return ret; + val = intel_freq_opcode(dev_priv, val); + + if (USES_GUC_SLPC(dev_priv)) { + ret = intel_guc_slpc_min_freq_set(&dev_priv->guc.slpc, val); + goto out; + } + intel_runtime_pm_get(dev_priv); mutex_lock(&dev_priv->pcu_lock); - val = intel_freq_opcode(dev_priv, val); - if (val < rps->min_freq || val > rps->max_freq || val > rps->max_freq_softlimit) { @@ -449,6 +480,7 @@ static ssize_t gt_min_freq_mhz_store(struct device *kdev, intel_runtime_pm_put(dev_priv); +out: return ret ?: count; } diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index 011e442..34a596
[Intel-gfx] [PATCH v12 16/17] drm/i915/guc/slpc: Add SLPC banner to RPS debugfs interfaces
When SLPC is controlling frequency requests, RPS state related to autotuning is no longer valid. Make user aware through banner upfront. Value read from register RPNSWREQ likely has the frequency requested last by GuC SLPC. v1: Replace HAS_SLPC with intel_slpc_active (Paulo) Avoid magic numbers (Nick) Use a function for repeated code (Jon) v2: Add "SLPC Active" to i915_frequency_info output and don't update cur_freq as it is driver internal request. (Chris) v3: Removing sysfs interface gt_req_freq_mhz out of this patch for proper division of functionality. (Sagar) v4: idle_freq, boost_freq are also not used with SLPC. v5: Added SLPC banner to i915_rps_boost_info and keep printing driver internal values. (Chris) v6: Commit message update. v7: Rebase. v8: Rebase. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1a66507..5d2ac24 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1068,6 +1068,9 @@ static int i915_frequency_info(struct seq_file *m, void *unused) struct intel_rps *rps = &dev_priv->gt_pm.rps; int ret = 0; + if (USES_GUC_SLPC(dev_priv)) + seq_puts(m, "SLPC Active\n"); + intel_runtime_pm_get(dev_priv); if (IS_GEN5(dev_priv)) { @@ -2209,6 +2212,9 @@ static int i915_rps_boost_info(struct seq_file *m, void *data) struct intel_rps *rps = &dev_priv->gt_pm.rps; struct drm_file *file; + if (USES_GUC_SLPC(dev_priv)) + seq_puts(m, "SLPC Active\n"); + seq_printf(m, "RPS enabled? %d\n", rps->enabled); seq_printf(m, "GPU busy? %s [%d requests]\n", yesno(dev_priv->gt.awake), dev_priv->gt.active_requests); -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v12 15/17] drm/i915/guc/slpc: Add i915_guc_slpc_info to debugfs
From: Tom O'Rourke i915_guc_slpc_info shows the contents of SLPC shared data parsed into text format. v1: Reformat slpc info (Radek). Squashed query task state info in slpc info, kunmap before seq_print (Paulo) Return void instead of ignored return value (Paulo) Avoid magic numbers and use local variables (Jon Bloomfield). Removed WARN_ON for checking msb of gtt address of shared gem obj. (Chris) Moved definition of power plan and power source to earlier patch in the series. drm/i915/slpc: Allocate/Release/Initialize SLPC shared data (Akash) v2-v3: Rebase. v4: Updated with GuC firmware v9. v5: Updated host2guc_slpc_query_task_state with struct slpc_input_event structure. Removed unnecessary checks of vma from i915_slpc_info. Created helpers for reading the SLPC shared data and string form of SLPC state. (Sagar) v6: s/i915_slpc_info/i915_guc_slpc_info. Prepared helpers platform_sku _to_string, power_plan_to_string and power_source_to_string. (Michal Wajdeczko) v7: Moved all SLPC data printing changes to guc_slpc.c and making use of drm_printer. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_debugfs.c | 10 ++ drivers/gpu/drm/i915/intel_guc_slpc.c | 193 ++ drivers/gpu/drm/i915/intel_guc_slpc.h | 2 + 3 files changed, 205 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f90ad52..1a66507 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1053,6 +1053,15 @@ DEFINE_SIMPLE_ATTRIBUTE(i915_next_seqno_fops, NULL, i915_next_seqno_set, "0x%llx\n"); +static int i915_guc_slpc_info(struct seq_file *m, void *unused) +{ + struct drm_i915_private *dev_priv = node_to_i915(m->private); + struct intel_guc_slpc *slpc = &dev_priv->guc.slpc; + struct drm_printer p = drm_seq_file_printer(m); + + return intel_guc_slpc_info(slpc, &p); +} + static int i915_frequency_info(struct seq_file *m, void *unused) { struct drm_i915_private *dev_priv = node_to_i915(m->private); @@ -5097,6 +5106,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_guc_load_err_log_dump", i915_guc_log_dump, 0, (void *)1}, {"i915_guc_stage_pool", i915_guc_stage_pool, 0}, {"i915_guc_slpc_params", i915_guc_slpc_params_info, 0}, + {"i915_guc_slpc_info", i915_guc_slpc_info, 0}, {"i915_huc_load_status", i915_huc_load_status_info, 0}, {"i915_frequency_info", i915_frequency_info, 0}, {"i915_hangcheck_info", i915_hangcheck_info, 0}, diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.c b/drivers/gpu/drm/i915/intel_guc_slpc.c index 7bd5e3e..94c6c19 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.c +++ b/drivers/gpu/drm/i915/intel_guc_slpc.c @@ -487,6 +487,199 @@ static void slpc_get_param(struct intel_guc_slpc *slpc, u32 id, kunmap_atomic(data); } +static const char *slpc_platform_sku_stringify(int platform_sku) +{ + const char *str = NULL; + + switch (platform_sku) { + case SLPC_PLATFORM_SKU_UNDEFINED: + str = "undefined"; + break; + case SLPC_PLATFORM_SKU_ULX: + str = "ULX"; + break; + case SLPC_PLATFORM_SKU_ULT: + str = "ULT"; + break; + case SLPC_PLATFORM_SKU_T: + str = "T"; + break; + case SLPC_PLATFORM_SKU_MOBL: + str = "Mobile"; + break; + case SLPC_PLATFORM_SKU_DT: + str = "DT"; + break; + case SLPC_PLATFORM_SKU_UNKNOWN: + default: + str = "unknown"; + break; + } + + return str; +} + +static const char *slpc_power_plan_stringify(int power_plan) +{ + const char *str = NULL; + + switch (power_plan) { + case SLPC_POWER_PLAN_UNDEFINED: + str = "undefined"; + break; + case SLPC_POWER_PLAN_BATTERY_SAVER: + str = "battery saver"; + break; + case SLPC_POWER_PLAN_BALANCED: + str = "balanced"; + break; + case SLPC_POWER_PLAN_PERFORMANCE: + str = "performance"; + break; + case SLPC_POWER_PLAN_UNKNOWN: + default: + str = "unknown"; + break; + } + + return str; +} + +static const char *slpc_power_source_stringify(int power_source) +{ + const char *str = NULL; + + switch (power_source) { + case SLPC_POWER_SOURCE_UNDEFINED: + str = "undefined"; + break; + case SLPC_POWER_SOURCE_AC: + str = "AC"; + break; +
[Intel-gfx] [PATCH v12 17/17] HAX: drm/i915/guc: Enable GuC
Signed-off-by: Sagar Arun Kamble --- drivers/gpu/drm/i915/i915_params.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 2484925..dd2de06 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -48,7 +48,7 @@ struct drm_printer; param(int, disable_power_well, -1) \ param(int, enable_ips, 1) \ param(int, invert_brightness, 0) \ - param(int, enable_guc, 0) \ + param(int, enable_guc, -1) \ param(int, guc_log_level, -1) \ param(char *, guc_firmware_path, NULL) \ param(char *, huc_firmware_path, NULL) \ -- 2.7.4 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Add support for GuC-based SLPC (rev12)
== Series Details == Series: Add support for GuC-based SLPC (rev12) URL : https://patchwork.freedesktop.org/series/2691/ State : warning == Summary == $ dim checkpatch origin/drm-tip d53e35c3815d drm/i915/guc/slpc: Add SLPC control to enable_guc modparam 6cf8c81b2bca drm/i915/guc/slpc: Disable host RPS bb01d5961927 drm/i915/guc/slpc: Lay out SLPC init/enable/disable/fini helpers -:106: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating? #106: new file mode 100644 total: 0 errors, 1 warnings, 0 checks, 126 lines checked bd7f17539b74 drm/i915/guc/slpc: Enable SLPC in GuC load control params 1ed1936a7f0d drm/i915/guc/slpc: Add SLPC communication interfaces -:61: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating? #61: new file mode 100644 total: 0 errors, 1 warnings, 0 checks, 219 lines checked b4db20e94cee drm/i915/guc/slpc: Allocate/initialize/release SLPC shared data -:64: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'dev_priv' - possible side-effects? #64: FILE: drivers/gpu/drm/i915/i915_drv.h:2419: +#define IS_ULX_SKU(dev_priv) (IS_SKL_ULX(dev_priv) || IS_KBL_ULX(dev_priv)) -:65: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'dev_priv' - possible side-effects? #65: FILE: drivers/gpu/drm/i915/i915_drv.h:2420: +#define IS_ULT_SKU(dev_priv) (IS_SKL_ULT(dev_priv) || \ +IS_KBL_ULT(dev_priv) || \ +IS_CFL_ULT(dev_priv)) total: 0 errors, 0 warnings, 2 checks, 240 lines checked b470c3d03b1c drm/i915/guc/slpc: Send RESET event to restart/enable SLPC tasks -:80: ERROR:SPACING: space required before the open parenthesis '(' #80: FILE: drivers/gpu/drm/i915/intel_guc_slpc.c:170: + switch(status) { total: 1 errors, 0 warnings, 0 checks, 253 lines checked 423af87658f2 drm/i915/guc/slpc: Send SHUTDOWN event to stop SLPC tasks 6b80339da56f drm/i915/guc/slpc: Reset SLPC on engine reset with flag TDR_OCCURRED 182447860555 drm/i915/guc/slpc: Add parameter set/unset/get, task control/status functions 8a14dde3f5d4 drm/i915/guc/slpc: Add support for sysfs min/max frequency control b1b7f3a4a9a0 drm/i915/guc/slpc: Add enable/disable controls for SLPC tasks 1683b3cafee8 drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing 9f4c9bd0a832 drm/i915/guc/slpc: Add debugfs support to read/write/revert the parameters -:75: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #75: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2807: + seq_printf(m, "%s=%u, override=%s\n", + slpc_params_desc[slpc->debug.param_id], -:116: CHECK:BRACES: braces {} should be used on all arms of this statement #116: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2848: + if (!strcmp(words[0], "read")) [...] + else if (!strcmp(words[0], "write")) [...] + else if (!strcmp(words[0], "revert")) [...] + else { [...] -:122: CHECK:BRACES: Unbalanced braces around else statement #122: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2854: + else { -:137: CHECK:SPACING: spaces preferred around that '-' (ctx:VxV) #137: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2869: + return (n_words-1); ^ -:141: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #141: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2873: +static ssize_t slpc_param_ctl_write(struct file *file, const char __user *ubuf, +size_t len, loff_t *offp) -:282: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'id >= SLPC_PARAM_TASK_ENABLE_GTPERF' #282: FILE: drivers/gpu/drm/i915/intel_guc_slpc.c:634: + if ((id >= SLPC_PARAM_TASK_ENABLE_GTPERF) && + (id <= SLPC_PARAM_TASK_DISABLE_DCC)) { -:282: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around 'id <= SLPC_PARAM_TASK_DISABLE_DCC' #282: FILE: drivers/gpu/drm/i915/intel_guc_slpc.c:634: + if ((id >= SLPC_PARAM_TASK_ENABLE_GTPERF) && + (id <= SLPC_PARAM_TASK_DISABLE_DCC)) { total: 0 errors, 0 warnings, 7 checks, 332 lines checked 18faa445aae6 drm/i915/guc/slpc: Add i915_guc_slpc_info to debugfs -:245: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #245: FILE: drivers/gpu/drm/i915/intel_guc_slpc.c:656: + intel_gpu_freq(dev_priv, + task_data->max_unslice_freq * GEN9_FREQ_SCALER)); -:248: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #248: FILE: drivers/gpu/drm/i915/intel_guc_slpc.c:659: + intel_gpu_freq(dev_priv, + task_data->min_unslice_freq * GEN9_FREQ_SCALER)); -:251: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #251: FILE: drivers/gpu/drm/i915/intel_guc_slpc.c:662: + intel_gpu_freq(dev_priv, + task_data->max_slice_freq * GEN9_FREQ_SCALER)); -:254: CHECK:P
[Intel-gfx] ✗ Fi.CI.SPARSE: warning for Add support for GuC-based SLPC (rev12)
== Series Details == Series: Add support for GuC-based SLPC (rev12) URL : https://patchwork.freedesktop.org/series/2691/ State : warning == Summary == $ dim sparse origin/drm-tip Commit: drm/i915/guc/slpc: Add SLPC control to enable_guc modparam Okay! Commit: drm/i915/guc/slpc: Disable host RPS Okay! Commit: drm/i915/guc/slpc: Lay out SLPC init/enable/disable/fini helpers Okay! Commit: drm/i915/guc/slpc: Enable SLPC in GuC load control params Okay! Commit: drm/i915/guc/slpc: Add SLPC communication interfaces Okay! Commit: drm/i915/guc/slpc: Allocate/initialize/release SLPC shared data Okay! Commit: drm/i915/guc/slpc: Send RESET event to restart/enable SLPC tasks Okay! Commit: drm/i915/guc/slpc: Send SHUTDOWN event to stop SLPC tasks Okay! Commit: drm/i915/guc/slpc: Reset SLPC on engine reset with flag TDR_OCCURRED Okay! Commit: drm/i915/guc/slpc: Add parameter set/unset/get, task control/status functions Okay! Commit: drm/i915/guc/slpc: Add support for sysfs min/max frequency control Okay! Commit: drm/i915/guc/slpc: Add enable/disable controls for SLPC tasks - +drivers/gpu/drm/i915/i915_debugfs.c:2697:30: warning: symbol 'i915_guc_slpc_gtperf_fops' was not declared. Should it be static? +drivers/gpu/drm/i915/i915_debugfs.c:2734:30: warning: symbol 'i915_guc_slpc_balancer_fops' was not declared. Should it be static? +drivers/gpu/drm/i915/i915_debugfs.c:2771:30: warning: symbol 'i915_guc_slpc_dcc_fops' was not declared. Should it be static? Commit: drm/i915/debugfs: Create generic string tokenize function and update CRC control parsing Okay! Commit: drm/i915/guc/slpc: Add debugfs support to read/write/revert the parameters +drivers/gpu/drm/i915/i915_debugfs.c:2925:30: warning: symbol 'i915_guc_slpc_param_ctl_fops' was not declared. Should it be static? Commit: drm/i915/guc/slpc: Add i915_guc_slpc_info to debugfs Okay! Commit: drm/i915/guc/slpc: Add SLPC banner to RPS debugfs interfaces Okay! Commit: HAX: drm/i915/guc: Enable GuC Okay! ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.BAT: failure for Add support for GuC-based SLPC (rev12)
== Series Details == Series: Add support for GuC-based SLPC (rev12) URL : https://patchwork.freedesktop.org/series/2691/ State : failure == Summary == Series 2691v12 Add support for GuC-based SLPC https://patchwork.freedesktop.org/api/1.0/series/2691/revisions/12/mbox/ Warning: Kernel 32bit buildtest failed https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8543/build_32bit.log Possible new issues: Test debugfs_test: Subgroup read_all_entries: pass -> DMESG-FAIL (fi-bdw-5557u) pass -> DMESG-FAIL (fi-bdw-gvtdvm) pass -> DMESG-FAIL (fi-blb-e6850) pass -> DMESG-FAIL (fi-bsw-n3050) pass -> DMESG-FAIL (fi-bwr-2160) pass -> DMESG-FAIL (fi-byt-j1900) pass -> DMESG-FAIL (fi-byt-n2820) pass -> DMESG-FAIL (fi-cnl-y3) pass -> DMESG-FAIL (fi-gdg-551) pass -> DMESG-FAIL (fi-hsw-4770) pass -> DMESG-FAIL (fi-ilk-650) pass -> DMESG-FAIL (fi-ivb-3520m) pass -> DMESG-FAIL (fi-ivb-3770) pass -> DMESG-FAIL (fi-pnv-d510) pass -> DMESG-FAIL (fi-skl-guc) pass -> DMESG-FAIL (fi-snb-2600) Test drv_hangman: Subgroup error-state-basic: pass -> DMESG-FAIL (fi-bdw-5557u) pass -> DMESG-FAIL (fi-bdw-gvtdvm) pass -> INCOMPLETE (fi-bsw-n3050) pass -> DMESG-FAIL (fi-cnl-y3) pass -> DMESG-FAIL (fi-glk-1) pass -> DMESG-FAIL (fi-skl-guc) Test drv_module_reload: Subgroup basic-reload: pass -> INCOMPLETE (fi-blb-e6850) pass -> INCOMPLETE (fi-bwr-2160) pass -> INCOMPLETE (fi-elk-e7500) pass -> INCOMPLETE (fi-gdg-551) pass -> INCOMPLETE (fi-ilk-650) pass -> INCOMPLETE (fi-pnv-d510) Test gem_basic: Subgroup create-close: pass -> INCOMPLETE (fi-glk-1) Test gem_busy: Subgroup basic-hang-default: pass -> INCOMPLETE (fi-bdw-5557u) pass -> INCOMPLETE (fi-bdw-gvtdvm) pass -> INCOMPLETE (fi-cnl-y3) Test pm_rps: Subgroup basic-api: pass -> INCOMPLETE (fi-byt-j1900) pass -> INCOMPLETE (fi-byt-n2820) pass -> INCOMPLETE (fi-hsw-4770) pass -> INCOMPLETE (fi-ivb-3520m) pass -> INCOMPLETE (fi-ivb-3770) pass -> FAIL (fi-skl-6770hq) pass -> INCOMPLETE (fi-snb-2520m) pass -> INCOMPLETE (fi-snb-2600) Known issues: Test debugfs_test: Subgroup read_all_entries: pass -> DMESG-FAIL (fi-elk-e7500) fdo#103989 +1 pass -> DMESG-FAIL (fi-glk-1) fdo#105421 pass -> DMESG-FAIL (fi-snb-2520m) fdo#103713 Test gem_busy: Subgroup basic-hang-default: pass -> INCOMPLETE (fi-skl-guc) fdo#104108 +1 fdo#103989 https://bugs.freedesktop.org/show_bug.cgi?id=103989 fdo#105421 https://bugs.freedesktop.org/show_bug.cgi?id=105421 fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713 fdo#104108 https://bugs.freedesktop.org/show_bug.cgi?id=104108 fi-bdw-5557u total:11 pass:8dwarn:0 dfail:2 fail:0 skip:0 fi-bdw-gvtdvmtotal:11 pass:8dwarn:0 dfail:2 fail:0 skip:0 fi-blb-e6850 total:282 pass:216 dwarn:1 dfail:1 fail:0 skip:63 fi-bsw-n3050 total:6pass:4dwarn:0 dfail:1 fail:0 skip:0 fi-bwr-2160 total:282 pass:176 dwarn:0 dfail:1 fail:0 skip:104 fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:518s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:515s fi-byt-j1900 total:250 pass:214 dwarn:0 dfail:1 fail:0 skip:34 fi-byt-n2820 total:250 pass:210 dwarn:0 dfail:1 fail:0 skip:38 fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:413s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:565s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:515s fi-cnl-y3total:11 pass:8dwarn:0 dfail:2 fail:0 skip:0 fi-elk-e7500 total:282 pass:222 dwarn:0 dfail:1 fail:0 skip:58 fi-gdg-551 total:282 pass:172 dwarn:0 dfail:1 fail:1 skip:107 fi-glk-1 total:8pass:5dwarn:0 dfail:2 fail:0 skip:0 fi-hsw-4770 total:250 pass:222 dwarn:0 dfail:1 fail:0 skip:26 fi-ilk-650 total:282 pass:221 dwarn:0 dfail:1 fail:0 skip:59 fi-i
Re: [Intel-gfx] [RFC v1] Data port coherency control for UMDs.
I think the adoption is not a problem here. If driver can query that patch is active on the specific setup, new capabilities will be always reported to the user. -Original Message- Quoting Dunajski, Bartosz (2018-03-26 12:46:13) > Here is pull request with patch usage: > https://github.com/intel/compute-runtime/pull/29 > > This patch is required to control data port coherency depending on incoming > workload into OpenCL API (fine-grain SVM requirement). Thank you for correcting the process. The original question however remains unanswered, how is it looking for the adoption of the new driver in distros? I was not able to find much by searching online, but by looking at the sources, I'd assume requiring a custom version of LLVM would be something to get rid of. Regards, Joonas ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for YCBCR 4:2:0/4:4:4 output support for LSPCON (rev4)
== Series Details == Series: YCBCR 4:2:0/4:4:4 output support for LSPCON (rev4) URL : https://patchwork.freedesktop.org/series/36068/ State : warning == Summary == $ dim checkpatch origin/drm-tip 5ab2dbdddfa3 drm/i915: Introduce CRTC output format -:86: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #86: FILE: drivers/gpu/drm/i915/intel_display.c:10690: + DRM_DEBUG_KMS("output format: %s\n", + output_formats(pipe_config->output_format)); total: 0 errors, 0 warnings, 1 checks, 139 lines checked c246f5eb5e66 drm/i915: Add CRTC output format YCBCR 4:2:0 -:88: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #88: FILE: drivers/gpu/drm/i915/intel_display.c:7659: +static void intel_get_crtc_ycbcr_config(struct intel_crtc *crtc, + struct intel_crtc_state *pipe_config) -:191: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #191: FILE: drivers/gpu/drm/i915/intel_display.c:10683: + if (format < INTEL_OUTPUT_FORMAT_RGB || + format > ARRAY_SIZE(output_format_str)) total: 0 errors, 0 warnings, 2 checks, 204 lines checked f3f94bb7c579 drm/i915: Add CRTC output format YCBCR 4:4:4 -:37: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #37: FILE: drivers/gpu/drm/i915/intel_color.c:153: + if (intel_crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 || + intel_crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) { total: 0 errors, 0 warnings, 1 checks, 58 lines checked ecbefc698d95 drm/i915: Check LSPCON vendor OUI daf03b9ae9bd drm/i915: Add AVI infoframe support for LSPCON 890b202f5791 drm/i915: Write AVI infoframes for MCA LSPCON -:38: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #38: FILE: drivers/gpu/drm/i915/intel_drv.h:2159: +void lspcon_write_infoframe(struct drm_encoder *encoder, +const struct intel_crtc_state *crtc_state, -:79: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #79: FILE: drivers/gpu/drm/i915/intel_lspcon.c:244: +static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux, +const uint8_t *buffer, ssize_t len) -:128: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #128: FILE: drivers/gpu/drm/i915/intel_lspcon.c:293: +void lspcon_write_infoframe(struct drm_encoder *encoder, +const struct intel_crtc_state *crtc_state, -:151: CHECK:LINE_SPACING: Please don't use multiple blank lines #151: FILE: drivers/gpu/drm/i915/intel_lspcon.c:316: + + total: 0 errors, 0 warnings, 4 checks, 110 lines checked 037713fcd3ef drm/i915: Write AVI infoframes for Parade LSPCON -:56: CHECK:BRACES: Blank lines aren't necessary after an open brace '{' #56: FILE: drivers/gpu/drm/i915/intel_lspcon.c:257: + for (retry = 0; retry < 5; retry++) { + -:76: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #76: FILE: drivers/gpu/drm/i915/intel_lspcon.c:277: +static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux, + uint8_t *avi_buf) -:85: CHECK:BRACES: Blank lines aren't necessary after an open brace '{' #85: FILE: drivers/gpu/drm/i915/intel_lspcon.c:286: + while (block_count < 4) { + -:88: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #88: FILE: drivers/gpu/drm/i915/intel_lspcon.c:289: + DRM_DEBUG_KMS("LSPCON FW not ready, block %d\n", + block_count); -:97: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #97: FILE: drivers/gpu/drm/i915/intel_lspcon.c:298: + DRM_ERROR("Failed to write AVI IF block %d\n", + block_count); -:112: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #112: FILE: drivers/gpu/drm/i915/intel_lspcon.c:313: + DRM_ERROR("Failed to update (0x%x), block %d\n", + reg, block_count); total: 0 errors, 0 warnings, 6 checks, 143 lines checked 8645b5d6cca7 drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON -:53: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV) #53: FILE: drivers/gpu/drm/i915/i915_reg.h:8721: +#define TRANS_MSA_SAMPLING_444(2<<1) ^ -:54: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV) #54: FILE: drivers/gpu/drm/i915/i915_reg.h:8722: +#define TRANS_MSA_CLRSP_YCBCR (2<<3) ^ total: 0 errors, 0 warnings, 2 checks, 128 lines checked ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.SPARSE: warning for YCBCR 4:2:0/4:4:4 output support for LSPCON (rev4)
== Series Details == Series: YCBCR 4:2:0/4:4:4 output support for LSPCON (rev4) URL : https://patchwork.freedesktop.org/series/36068/ State : warning == Summary == $ dim sparse origin/drm-tip Commit: drm/i915: Introduce CRTC output format Okay! Commit: drm/i915: Add CRTC output format YCBCR 4:2:0 Okay! Commit: drm/i915: Add CRTC output format YCBCR 4:4:4 Okay! Commit: drm/i915: Check LSPCON vendor OUI Okay! Commit: drm/i915: Add AVI infoframe support for LSPCON Okay! Commit: drm/i915: Write AVI infoframes for MCA LSPCON +drivers/gpu/drm/i915/intel_hdmi.c:2283:57:expected void ( *write_infoframe )( ... ) +drivers/gpu/drm/i915/intel_hdmi.c:2283:57:got void ( * )( ... ) +drivers/gpu/drm/i915/intel_hdmi.c:2283:57: warning: incorrect type in assignment (incompatible argument 3 (different signedness)) Commit: drm/i915: Write AVI infoframes for Parade LSPCON Okay! Commit: drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON Okay! ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.BAT: warning for YCBCR 4:2:0/4:4:4 output support for LSPCON (rev4)
== Series Details == Series: YCBCR 4:2:0/4:4:4 output support for LSPCON (rev4) URL : https://patchwork.freedesktop.org/series/36068/ State : warning == Summary == Series 36068v4 YCBCR 4:2:0/4:4:4 output support for LSPCON https://patchwork.freedesktop.org/api/1.0/series/36068/revisions/4/mbox/ Possible new issues: Test kms_pipe_crc_basic: Subgroup suspend-read-crc-pipe-a: pass -> DMESG-WARN (fi-kbl-7567u) Subgroup suspend-read-crc-pipe-b: pass -> DMESG-WARN (fi-kbl-7567u) Subgroup suspend-read-crc-pipe-c: pass -> DMESG-WARN (fi-kbl-7567u) Known issues: Test gem_exec_suspend: Subgroup basic-s3: pass -> DMESG-WARN (fi-kbl-7567u) fdo#103665 incomplete -> PASS (fi-skl-6700k2) fdo#104108 Test kms_pipe_crc_basic: Subgroup suspend-read-crc-pipe-a: dmesg-warn -> PASS (fi-cnl-y3) fdo#103191 Test prime_vgem: Subgroup basic-fence-flip: pass -> FAIL (fi-ilk-650) fdo#104008 fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665 fdo#104108 https://bugs.freedesktop.org/show_bug.cgi?id=104108 fdo#103191 https://bugs.freedesktop.org/show_bug.cgi?id=103191 fdo#104008 https://bugs.freedesktop.org/show_bug.cgi?id=104008 fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:431s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:447s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:380s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:539s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:294s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:517s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:517s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:511s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:411s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:562s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:518s fi-cnl-y3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:585s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:421s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:316s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:535s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:404s fi-ilk-650 total:285 pass:224 dwarn:0 dfail:0 fail:1 skip:60 time:421s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:469s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:430s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:474s fi-kbl-7567u total:285 pass:261 dwarn:4 dfail:0 fail:0 skip:20 time:462s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:510s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:658s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:440s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:537s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:511s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:509s fi-skl-guc total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:428s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:443s fi-snb-2520m total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:567s fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:402s Blacklisted hosts: fi-cnl-psr total:285 pass:256 dwarn:3 dfail:0 fail:0 skip:26 time:517s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:484s 9829fcd7ae99d5955bb76a8fb8060e63339d7c9d drm-tip: 2018y-03m-29d-19h-56m-48s UTC integration manifest 8645b5d6cca7 drm/i915: Add YCBCR 4:2:0/4:4:4 support for LSPCON 037713fcd3ef drm/i915: Write AVI infoframes for Parade LSPCON 890b202f5791 drm/i915: Write AVI infoframes for MCA LSPCON daf03b9ae9bd drm/i915: Add AVI infoframe support for LSPCON ecbefc698d95 drm/i915: Check LSPCON vendor OUI f3f94bb7c579 drm/i915: Add CRTC output format YCBCR 4:4:4 c246f5eb5e66 drm/i915: Add CRTC output format YCBCR 4:2:0 5ab2dbdddfa3 drm/i915: Introduce CRTC output format == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8544/issues.html ___ Intel-gfx mailing list Intel-gfx@lists
[Intel-gfx] [PATCH 02/17] drm/i915/execlists: Set queue priority from secondary port
We can refine our current execlists->queue_priority if we inspect ELSP[1] rather than the head of the unsubmitted queue. Currently, we use the unsubmitted queue and say that if a subsequent request is more than important than the current queue, we will rerun the submission tasklet to evaluate the need for preemption. However, we only want to preempt if we need to jump ahead of a currently executing request in ELSP. The second reason for running the submission tasklet is amalgamate requests into the active context on ELSP[0] to avoid a stall when ELSP[0] drains. (Though repeatedly amalgamating requests into the active context and triggering many lite-restore is off question gain, the goal really is to put a context into ELSP[1] to cover the interrupt.) So if instead of looking at the head of the queue, we look at the context in ELSP[1] we can answer both of the questions more accurately -- we don't need to rerun the submission tasklet unless our new request is important enough to feed into, at least, ELSP[1]. References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Michel Thierry Cc: Mika Kuoppala Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_lrc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2d2d33becce3..a3fd9683f9d1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -712,7 +712,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) kmem_cache_free(engine->i915->priorities, p); } done: - execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; + execlists->queue_priority = + port != execlists->port ? rq_prio(last) : INT_MIN; execlists->first = rb; if (submit) port_assign(port, last); -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 04/17] drm/i915: Move engine reset prepare/finish to backends
In preparation to more carefully handling incomplete preemption during reset by execlists, we move the existing code wholesale to the backends under a couple of new reset vfuncs. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Reviewed-by: Jeff McGee --- drivers/gpu/drm/i915/i915_gem.c | 47 +++--- drivers/gpu/drm/i915/intel_lrc.c| 59 +++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 23 +++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 9 +++-- 4 files changed, 88 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9650a7b10c5f..038867c96809 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2917,7 +2917,7 @@ static bool engine_stalled(struct intel_engine_cs *engine) struct i915_request * i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) { - struct i915_request *request = NULL; + struct i915_request *request; /* * During the reset sequence, we must prevent the engine from @@ -2940,40 +2940,7 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ kthread_park(engine->breadcrumbs.signaler); - /* -* Prevent request submission to the hardware until we have -* completed the reset in i915_gem_reset_finish(). If a request -* is completed by one engine, it may then queue a request -* to a second via its execlists->tasklet *just* as we are -* calling engine->init_hw() and also writing the ELSP. -* Turning off the execlists->tasklet until the reset is over -* prevents the race. -* -* Note that this needs to be a single atomic operation on the -* tasklet (flush existing tasks, prevent new tasks) to prevent -* a race between reset and set-wedged. It is not, so we do the best -* we can atm and make sure we don't lock the machine up in the more -* common case of recursively being called from set-wedged from inside -* i915_reset. -*/ - if (!atomic_read(&engine->execlists.tasklet.count)) - tasklet_kill(&engine->execlists.tasklet); - tasklet_disable(&engine->execlists.tasklet); - - /* -* We're using worker to queue preemption requests from the tasklet in -* GuC submission mode. -* Even though tasklet was disabled, we may still have a worker queued. -* Let's make sure that all workers scheduled before disabling the -* tasklet are completed before continuing with the reset. -*/ - if (engine->i915->guc.preempt_wq) - flush_workqueue(engine->i915->guc.preempt_wq); - - if (engine->irq_seqno_barrier) - engine->irq_seqno_barrier(engine); - - request = i915_gem_find_active_request(engine); + request = engine->reset.prepare(engine); if (request && request->fence.error == -EIO) request = ERR_PTR(-EIO); /* Previous reset failed! */ @@ -3114,13 +3081,8 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine, if (request) request = i915_gem_reset_request(engine, request); - if (request) { - DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n", -engine->name, request->global_seqno); - } - /* Setup the CS to resume from the breadcrumb of the hung request */ - engine->reset_hw(engine, request); + engine->reset.reset(engine, request); } void i915_gem_reset(struct drm_i915_private *dev_priv) @@ -3172,7 +3134,8 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { - tasklet_enable(&engine->execlists.tasklet); + engine->reset.finish(engine); + kthread_unpark(engine->breadcrumbs.signaler); intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 51e930323626..42f9af625e88 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1732,8 +1732,48 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) return init_workarounds_ring(engine); } -static void reset_common_ring(struct intel_engine_cs *engine, - struct i915_request *request) +static struct i915_request * +execlists_reset_prepare(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + GEM_TRACE("%s\n", engine->name); + + /* +* Prevent request submission to the hardware until we have +* completed the reset in i915_gem_reset_finish(). If a request +* is completed by one engine, it may then queue a request +* to a second
[Intel-gfx] [PATCH 06/17] drm/i915/execlists: Flush pending preemption events during reset
Catch up with the inflight CSB events, after disabling the tasklet before deciding which request was truly guilty of hanging the GPU. v2: Restore checking of use_csb_mmio on every loop, don't forget old vgpu. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 127 +++ 1 file changed, 87 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5c1324c37549..6217118633fd 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -889,34 +889,14 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) local_irq_restore(flags); } -/* - * Check the unread Context Status Buffers and manage the submission of new - * contexts to the ELSP accordingly. - */ -static void execlists_submission_tasklet(unsigned long data) +static void process_csb(struct intel_engine_cs *engine) { - struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; - struct drm_i915_private *dev_priv = engine->i915; + struct drm_i915_private *i915 = engine->i915; bool fw = false; - /* -* We can skip acquiring intel_runtime_pm_get() here as it was taken -* on our behalf by the request (see i915_gem_mark_busy()) and it will -* not be relinquished until the device is idle (see -* i915_gem_idle_work_handler()). As a precaution, we make sure -* that all ELSP are drained i.e. we have processed the CSB, -* before allowing ourselves to idle and calling intel_runtime_pm_put(). -*/ - GEM_BUG_ON(!dev_priv->gt.awake); - - /* -* Prefer doing test_and_clear_bit() as a two stage operation to avoid -* imposing the cost of a locked atomic transaction when submitting a -* new request (outside of the context-switch interrupt). -*/ - while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { + do { /* The HWSP contains a (cacheable) mirror of the CSB */ const u32 *buf = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; @@ -924,28 +904,27 @@ static void execlists_submission_tasklet(unsigned long data) if (unlikely(execlists->csb_use_mmio)) { buf = (u32 * __force) - (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); - execlists->csb_head = -1; /* force mmio read of CSB ptrs */ + (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); + execlists->csb_head = -1; /* force mmio read of CSB */ } /* Clear before reading to catch new interrupts */ clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); smp_mb__after_atomic(); - if (unlikely(execlists->csb_head == -1)) { /* following a reset */ + if (unlikely(execlists->csb_head == -1)) { /* after a reset */ if (!fw) { - intel_uncore_forcewake_get(dev_priv, - execlists->fw_domains); + intel_uncore_forcewake_get(i915, execlists->fw_domains); fw = true; } - head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); + head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); tail = GEN8_CSB_WRITE_PTR(head); head = GEN8_CSB_READ_PTR(head); execlists->csb_head = head; } else { const int write_idx = - intel_hws_csb_write_index(dev_priv) - + intel_hws_csb_write_index(i915) - I915_HWS_CSB_BUF0_INDEX; head = execlists->csb_head; @@ -953,8 +932,8 @@ static void execlists_submission_tasklet(unsigned long data) } GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", engine->name, - head, GEN8_CSB_READ_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?", - tail, GEN8_CSB_WRITE_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?"); + head, GEN8_CSB_READ_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine,
[Intel-gfx] [PATCH 09/17] drm/i915: Combine tasklet_kill and tasklet_disable
Ideally, we want to atomically flush and disable the tasklet before resetting the GPU. At present, we rely on being the only part to touch our tasklet and serialisation of the reset process to ensure that we can suspend the tasklet from the mix of reset/wedge pathways. In this patch, we move the tasklet abuse into its own function and tweak it such that we only do a synchronous operation the first time it is disabled around the reset. This allows us to avoid the sync inside a softirq context in subsequent patches. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cba1ecda126a..8fe9e62c5d18 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1745,6 +1745,16 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) return init_workarounds_ring(engine); } +static void tasklet_kill_and_disable(struct tasklet_struct *t) +{ + if (!atomic_read(&t->count)) + tasklet_kill(t); + + if (atomic_inc_return(&t->count) == 1) + tasklet_unlock_wait(t); + smp_mb(); +} + static struct i915_request * execlists_reset_prepare(struct intel_engine_cs *engine) { @@ -1769,9 +1779,7 @@ execlists_reset_prepare(struct intel_engine_cs *engine) * common case of recursively being called from set-wedged from inside * i915_reset. */ - if (!atomic_read(&execlists->tasklet.count)) - tasklet_kill(&execlists->tasklet); - tasklet_disable(&execlists->tasklet); + tasklet_kill_and_disable(&execlists->tasklet); /* * We want to flush the pending context switches, having disabled -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/17] drm/i915: Split execlists/guc reset prepartions
In the next patch, we will make the execlists reset prepare callback take into account preemption by flushing the context-switch handler. This is not applicable to the GuC submission backend, so split the two into their own backend callbacks. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Reviewed-by: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_submission.c | 41 + drivers/gpu/drm/i915/intel_lrc.c| 11 +--- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index ef2e29959c5b..0e0655430480 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -784,6 +784,46 @@ static void guc_submission_tasklet(unsigned long data) guc_dequeue(engine); } +static struct i915_request * +guc_reset_prepare(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + GEM_TRACE("%s\n", engine->name); + + /* +* Prevent request submission to the hardware until we have +* completed the reset in i915_gem_reset_finish(). If a request +* is completed by one engine, it may then queue a request +* to a second via its execlists->tasklet *just* as we are +* calling engine->init_hw() and also writing the ELSP. +* Turning off the execlists->tasklet until the reset is over +* prevents the race. +* +* Note that this needs to be a single atomic operation on the +* tasklet (flush existing tasks, prevent new tasks) to prevent +* a race between reset and set-wedged. It is not, so we do the best +* we can atm and make sure we don't lock the machine up in the more +* common case of recursively being called from set-wedged from inside +* i915_reset. +*/ + if (!atomic_read(&execlists->tasklet.count)) + tasklet_kill(&execlists->tasklet); + tasklet_disable(&execlists->tasklet); + + /* +* We're using worker to queue preemption requests from the tasklet in +* GuC submission mode. +* Even though tasklet was disabled, we may still have a worker queued. +* Let's make sure that all workers scheduled before disabling the +* tasklet are completed before continuing with the reset. +*/ + if (engine->i915->guc.preempt_wq) + flush_workqueue(engine->i915->guc.preempt_wq); + + return i915_gem_find_active_request(engine); +} + /* * Everything below here is concerned with setup & teardown, and is * therefore not part of the somewhat time-critical batch-submission @@ -1243,6 +1283,7 @@ int intel_guc_submission_enable(struct intel_guc *guc) &engine->execlists; execlists->tasklet.func = guc_submission_tasklet; + engine->reset.prepare = guc_reset_prepare; engine->park = guc_submission_park; engine->unpark = guc_submission_unpark; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 42f9af625e88..5c1324c37549 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1759,16 +1759,6 @@ execlists_reset_prepare(struct intel_engine_cs *engine) tasklet_kill(&execlists->tasklet); tasklet_disable(&execlists->tasklet); - /* -* We're using worker to queue preemption requests from the tasklet in -* GuC submission mode. -* Even though tasklet was disabled, we may still have a worker queued. -* Let's make sure that all workers scheduled before disabling the -* tasklet are completed before continuing with the reset. -*/ - if (engine->i915->guc.preempt_wq) - flush_workqueue(engine->i915->guc.preempt_wq); - return i915_gem_find_active_request(engine); } @@ -2158,6 +2148,7 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine) engine->cancel_requests = execlists_cancel_requests; engine->schedule = execlists_schedule; engine->execlists.tasklet.func = execlists_submission_tasklet; + engine->reset.prepare = execlists_reset_prepare; engine->park = NULL; engine->unpark = NULL; -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 16/17] drm/i915: Use a preemption timeout to enforce interactivity
Use a liberal timeout of 20ms to ensure that the rendering for an interactive pageflip is started in a timely fashion, and that user interaction is not blocked by GPU, or CPU, hogs. This is at the cost of resetting whoever was blocking the preemption, likely leading to that context/process being banned from submitting future requests. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 18 ++ drivers/gpu/drm/i915/intel_display.c | 18 +- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 800230ba1c3b..87388feb973d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3150,8 +3150,9 @@ int i915_gem_object_wait(struct drm_i915_gem_object *obj, struct intel_rps_client *rps); int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, unsigned int flags, - int priority); + int priority, unsigned int timeout); #define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX +#define I915_PREEMPTION_TIMEOUT_DISPLAY (20 * 1000 * 1000) /* 20 ms */ int __must_check i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a860d501134e..3760133ca08e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -469,7 +469,8 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, return timeout; } -static void __fence_set_priority(struct dma_fence *fence, int prio) +static void __fence_set_priority(struct dma_fence *fence, +int prio, unsigned int timeout) { struct i915_request *rq; struct intel_engine_cs *engine; @@ -482,11 +483,12 @@ static void __fence_set_priority(struct dma_fence *fence, int prio) rcu_read_lock(); if (engine->schedule) - engine->schedule(rq, prio, 0); + engine->schedule(rq, prio, timeout); rcu_read_unlock(); } -static void fence_set_priority(struct dma_fence *fence, int prio) +static void fence_set_priority(struct dma_fence *fence, + int prio, unsigned int timeout) { /* Recurse once into a fence-array */ if (dma_fence_is_array(fence)) { @@ -494,16 +496,16 @@ static void fence_set_priority(struct dma_fence *fence, int prio) int i; for (i = 0; i < array->num_fences; i++) - __fence_set_priority(array->fences[i], prio); + __fence_set_priority(array->fences[i], prio, timeout); } else { - __fence_set_priority(fence, prio); + __fence_set_priority(fence, prio, timeout); } } int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, unsigned int flags, - int prio) + int prio, unsigned int timeout) { struct dma_fence *excl; @@ -518,7 +520,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, return ret; for (i = 0; i < count; i++) { - fence_set_priority(shared[i], prio); + fence_set_priority(shared[i], prio, timeout); dma_fence_put(shared[i]); } @@ -528,7 +530,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, } if (excl) { - fence_set_priority(excl, prio); + fence_set_priority(excl, prio, timeout); dma_fence_put(excl); } return 0; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 415fb8cf2cf4..8ce2019746cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12788,7 +12788,23 @@ intel_prepare_plane_fb(struct drm_plane *plane, ret = intel_plane_pin_fb(to_intel_plane_state(new_state)); - i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY); + /* +* Reschedule our dependencies, and ensure we run within a timeout. +* +* Note that if the timeout is exceeded, then whoever was running that +* prevented us from acquiring the GPU is declared rogue and reset. An +* unresponsive process will then be banned in order to preserve +* interactivity. Since this can be seen as a bit heavy-handed, we +* select a timeout for when the dropped frames start to become a +* noticeable nuisance for the user (20 ms, i.e. preemption was blocked +* for more than a frame). Note, this is only a timeout for a delay in +* preempting the curre
[Intel-gfx] [PATCH 10/17] drm/i915: Stop parking the signaler around reset
We cannot call kthread_park() from softirq context, so let's avoid it entirely during the reset. We wanted to suspend the signaler so that it would not mark a request as complete at the same time as we marked it as being in error. Instead of parking the signaling, stop the engine from advancing so that the GPU doesn't emit the breadcrumb for our choosen "guilty" request. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem.c | 14 -- drivers/gpu/drm/i915/intel_lrc.c| 21 + drivers/gpu/drm/i915/intel_ringbuffer.c | 18 ++ 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 038867c96809..8a6acb1d5ad3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2928,18 +2928,6 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); - /* -* Prevent the signaler thread from updating the request -* state (by calling dma_fence_signal) as we are processing -* the reset. The write from the GPU of the seqno is -* asynchronous and the signaler thread may see a different -* value to us and declare the request complete, even though -* the reset routine have picked that request as the active -* (incomplete) request. This conflict is not handled -* gracefully! -*/ - kthread_park(engine->breadcrumbs.signaler); - request = engine->reset.prepare(engine); if (request && request->fence.error == -EIO) request = ERR_PTR(-EIO); /* Previous reset failed! */ @@ -3136,8 +3124,6 @@ void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { engine->reset.finish(engine); - kthread_unpark(engine->breadcrumbs.signaler); - intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8fe9e62c5d18..abae1d8332d0 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1755,6 +1755,21 @@ static void tasklet_kill_and_disable(struct tasklet_struct *t) smp_mb(); } +static void set_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (__intel_wait_for_register_fw(dev_priv, +mode, MODE_IDLE, MODE_IDLE, +1000, 0, +NULL)) + DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", +engine->name); +} + static struct i915_request * execlists_reset_prepare(struct intel_engine_cs *engine) { @@ -1801,6 +1816,12 @@ execlists_reset_prepare(struct intel_engine_cs *engine) if (request) { unsigned long flags; + /* +* Prevent the breadcrumb from advancing before we decide +* which request is currently active. +*/ + set_stop_engine(engine); + spin_lock_irqsave(&engine->timeline->lock, flags); list_for_each_entry_from_reverse(request, &engine->timeline->requests, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5dadbc435c0e..226c00aecd8a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -530,8 +530,26 @@ static int init_ring_common(struct intel_engine_cs *engine) return ret; } +static void set_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (__intel_wait_for_register_fw(dev_priv, +mode, MODE_IDLE, MODE_IDLE, +1000, 0, +NULL)) + DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", +engine->name); +} + static struct i915_request *reset_prepare(struct intel_engine_cs *engine) { + if (INTEL_GEN(engine->i915) >= 3) + set_stop_engine(engine); + if (engine->irq_seqno_barrier) engine->irq_seqno_barrier(engine); -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https:/
[Intel-gfx] [PATCH 12/17] drm/i915: Allow init_breadcrumbs to be used from irq context
In order to support engine reset from irq (timer) context, we need to be able to re-initialise the breadcrumbs. So we need to promote the plain spin_lock_irq to a safe spin_lock_irqsave. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 0a2128c6b418..ca0b04d9747c 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -846,8 +846,9 @@ static void cancel_fake_irq(struct intel_engine_cs *engine) void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; + unsigned long flags; - spin_lock_irq(&b->irq_lock); + spin_lock_irqsave(&b->irq_lock, flags); /* * Leave the fake_irq timer enabled (if it is running), but clear the @@ -871,7 +872,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) */ clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); - spin_unlock_irq(&b->irq_lock); + spin_unlock_irqrestore(&b->irq_lock, flags); } void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 08/17] drm/i915/breadcrumbs: Keep the fake irq armed across reset
Instead of synchronously cancelling the timer and re-enabling it inside the reset callbacks, keep the timer enabled and let it die on its next wakeup if no longer required. This allows intel_engine_reset_breadcrumbs() to be used from an atomic (timer/softirq) context such as required for resetting an engine. It also allows us to react better to the user poking around debugfs for testing missed irqs. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 27 +++ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 671a6d61e29d..0a2128c6b418 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -130,11 +130,12 @@ static void intel_breadcrumbs_hangcheck(struct timer_list *t) static void intel_breadcrumbs_fake_irq(struct timer_list *t) { - struct intel_engine_cs *engine = from_timer(engine, t, - breadcrumbs.fake_irq); + struct intel_engine_cs *engine = + from_timer(engine, t, breadcrumbs.fake_irq); struct intel_breadcrumbs *b = &engine->breadcrumbs; - /* The timer persists in case we cannot enable interrupts, + /* +* The timer persists in case we cannot enable interrupts, * or if we have previously seen seqno/interrupt incoherency * ("missed interrupt" syndrome, better known as a "missed breadcrumb"). * Here the worker will wake up every jiffie in order to kick the @@ -148,6 +149,12 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t) if (!b->irq_armed) return; + /* If the user has disabled the fake-irq, restore the hangchecking */ + if (!test_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings)) { + mod_timer(&b->hangcheck, wait_timeout()); + return; + } + mod_timer(&b->fake_irq, jiffies + 1); } @@ -840,15 +847,22 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; - cancel_fake_irq(engine); spin_lock_irq(&b->irq_lock); + /* +* Leave the fake_irq timer enabled (if it is running), but clear the +* bit so that it turns itself off on its next wake up and goes back +* to the long hangcheck interval if still required. +*/ + clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings); + if (b->irq_enabled) irq_enable(engine); else irq_disable(engine); - /* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the + /* +* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the * GPU is active and may have already executed the MI_USER_INTERRUPT * before the CPU is ready to receive. However, the engine is currently * idle (we haven't started it yet), there is no possibility for a @@ -857,9 +871,6 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) */ clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); - if (b->irq_armed) - enable_fake_irq(b); - spin_unlock_irq(&b->irq_lock); } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 07/17] drm/i915/selftests: Add basic sanitychecks for execlists
Before adding a new feature to execlists submission, we should endeavour to cover the baseline behaviour with selftests. So start the ball rolling. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin Cc: Mika Kuoppala --- drivers/gpu/drm/i915/intel_lrc.c | 4 + .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + drivers/gpu/drm/i915/selftests/intel_lrc.c | 499 + 3 files changed, 504 insertions(+) create mode 100644 drivers/gpu/drm/i915/selftests/intel_lrc.c diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6217118633fd..cba1ecda126a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2693,3 +2693,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv) } } } + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +#include "selftests/intel_lrc.c" +#endif diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index 9c76f0305b6a..8bf6aa573226 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h @@ -20,4 +20,5 @@ selftest(evict, i915_gem_evict_live_selftests) selftest(hugepages, i915_gem_huge_page_live_selftests) selftest(contexts, i915_gem_context_live_selftests) selftest(hangcheck, intel_hangcheck_live_selftests) +selftest(execlists, intel_execlists_live_selftests) selftest(guc, intel_guc_live_selftest) diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c new file mode 100644 index ..ca8bf7dd4fd3 --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -0,0 +1,499 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2018 Intel Corporation + */ + +#include "../i915_selftest.h" + +#include "mock_context.h" + +struct spinner { + struct drm_i915_private *i915; + struct drm_i915_gem_object *hws; + struct drm_i915_gem_object *obj; + u32 *seqno; + u32 *batch; +}; + +static int spinner_init(struct spinner *spin, struct drm_i915_private *i915) +{ + void *vaddr; + int err; + + GEM_BUG_ON(INTEL_GEN(i915) < 8); + + memset(spin, 0, sizeof(*spin)); + spin->i915 = i915; + + spin->hws = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(spin->hws)) { + err = PTR_ERR(spin->hws); + goto err; + } + + spin->obj = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(spin->obj)) { + err = PTR_ERR(spin->obj); + goto err_hws; + } + + i915_gem_object_set_cache_level(spin->hws, I915_CACHE_LLC); + vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto err_obj; + } + spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); + + vaddr = i915_gem_object_pin_map(spin->obj, + HAS_LLC(i915) ? I915_MAP_WB : I915_MAP_WC); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto err_unpin_hws; + } + spin->batch = vaddr; + + return 0; + +err_unpin_hws: + i915_gem_object_unpin_map(spin->hws); +err_obj: + i915_gem_object_put(spin->obj); +err_hws: + i915_gem_object_put(spin->hws); +err: + return err; +} + +static u64 hws_address(const struct i915_vma *hws, + const struct i915_request *rq) +{ + return hws->node.start + offset_in_page(sizeof(u32)*rq->fence.context); +} + +static int emit_recurse_batch(struct spinner *spin, + struct i915_request *rq, + u32 arbitration_command) +{ + struct i915_address_space *vm = &rq->ctx->ppgtt->base; + struct i915_vma *hws, *vma; + u32 *batch; + int err; + + vma = i915_vma_instance(spin->obj, vm, NULL); + if (IS_ERR(vma)) + return PTR_ERR(vma); + + hws = i915_vma_instance(spin->hws, vm, NULL); + if (IS_ERR(hws)) + return PTR_ERR(hws); + + err = i915_vma_pin(vma, 0, 0, PIN_USER); + if (err) + return err; + + err = i915_vma_pin(hws, 0, 0, PIN_USER); + if (err) + goto unpin_vma; + + i915_vma_move_to_active(vma, rq, 0); + if (!i915_gem_object_has_active_reference(vma->obj)) { + i915_gem_object_get(vma->obj); + i915_gem_object_set_active_reference(vma->obj); + } + + i915_vma_move_to_active(hws, rq, 0); + if (!i915_gem_object_has_active_reference(hws->obj)) { + i915_gem_object_get(hws->obj); + i915_gem_object_set_active_reference(hws->obj); + } + + batch = spin->batch; + + *batch++ = MI_STORE_DWO
[Intel-gfx] [PATCH 14/17] drm/i915/execlists: Try preempt-reset from softirq context
When circumstances allow, trying resetting the engine directly from the preemption timeout handler. As this is softirq context, we have to be careful both not to sleep and not to spin on anything we may be interrupting (e.g. the submission tasklet). Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_lrc.c | 31 +++- drivers/gpu/drm/i915/selftests/intel_lrc.c | 121 + 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cb11b14cd93c..dfbf0913f14e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -549,6 +549,33 @@ static void inject_preempt_context(struct intel_engine_cs *engine) execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } +static int try_preempt_reset(struct intel_engine_execlists *execlists) +{ + struct intel_engine_cs *engine = + container_of(execlists, typeof(*engine), execlists); + int err = -EBUSY; + + if (!test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted) && + tasklet_trylock(&execlists->tasklet)) { + unsigned long *lock = &engine->i915->gpu_error.flags; + unsigned int bit = I915_RESET_ENGINE + engine->id; + + if (!test_and_set_bit(bit, lock)) { + tasklet_disable_nosync(&engine->execlists.tasklet); + err = i915_reset_engine(engine, + "preemption time out"); + tasklet_enable(&engine->execlists.tasklet); + + clear_bit(bit, lock); + wake_up_bit(lock, bit); + } + + tasklet_unlock(&execlists->tasklet); + } + + return err; +} + static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) { struct intel_engine_execlists *execlists = @@ -562,7 +589,9 @@ static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT)) return HRTIMER_NORESTART; - queue_work(system_highpri_wq, &execlists->preempt_reset); + if (try_preempt_reset(execlists)) + queue_work(system_highpri_wq, &execlists->preempt_reset); + return HRTIMER_NORESTART; } diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index b9c9c1d26cc1..626acf46f65e 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -553,6 +553,126 @@ static int live_preempt_timeout(void *arg) return err; } +static void __softirq_begin(void) +{ + local_bh_disable(); +} + +static void __softirq_end(void) +{ + local_bh_enable(); +} + +static void __hardirq_begin(void) +{ + local_irq_disable(); +} + +static void __hardirq_end(void) +{ + local_irq_enable(); +} + +static int live_preempt_reset(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_engine_cs *engine; + struct i915_gem_context *ctx; + enum intel_engine_id id; + struct spinner spin; + int err = -ENOMEM; + + if (!HAS_LOGICAL_RING_PREEMPTION(i915)) + return 0; + + mutex_lock(&i915->drm.struct_mutex); + + if (spinner_init(&spin, i915)) + goto err_unlock; + + ctx= kernel_context(i915); + if (!ctx) + goto err_spin; + + for_each_engine(engine, i915, id) { + static const struct { + const char *name; + void (*critical_section_begin)(void); + void (*critical_section_end)(void); + } phases[] = { + { "softirq", __softirq_begin, __softirq_end }, + { "hardirq", __hardirq_begin, __hardirq_end }, + { } + }; + const typeof(*phases) *p; + + for (p = phases; p->name; p++) { + struct i915_request *rq; + + rq = spinner_create_request(&spin, ctx, engine, + MI_NOOP); + if (IS_ERR(rq)) { + err = PTR_ERR(rq); + goto err_ctx; + } + + i915_request_add(rq); + if (!wait_for_spinner(&spin, rq)) { + i915_gem_set_wedged(i915); + err = -EIO; + goto err_ctx; + } + + /* Flush to give try_preempt_reset a chance */ + do { + tasklet_schedule(&engine->ex
[Intel-gfx] [PATCH 13/17] drm/i915/execlists: Force preemption via reset on timeout
Install a timer when trying to preempt on behalf of an important context such that if the active context does not honour the preemption request within the desired timeout, then we reset the GPU to allow the important context to run. v2: Install the timer on scheduling the preempt request; long before we even try to inject preemption into the ELSP, as the tasklet/injection may itself be blocked. v3: Update the guc to handle the preemption/tasklet timer. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_guc_submission.c | 4 ++ drivers/gpu/drm/i915/intel_lrc.c| 82 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 8 ++- drivers/gpu/drm/i915/selftests/intel_lrc.c | 66 +++ 4 files changed, 151 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 0e0655430480..d10068579285 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -627,6 +627,9 @@ static void complete_preempt_context(struct intel_engine_cs *engine) GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); + hrtimer_try_to_cancel(&execlists->preempt_timer); + execlists_cancel_port_requests(execlists); execlists_unwind_incomplete_requests(execlists); @@ -739,6 +742,7 @@ static void guc_dequeue(struct intel_engine_cs *engine) kmem_cache_free(engine->i915->priorities, p); } done: + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; execlists->first = rb; if (submit) { diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index abae1d8332d0..cb11b14cd93c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -549,10 +549,50 @@ static void inject_preempt_context(struct intel_engine_cs *engine) execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } +static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) +{ + struct intel_engine_execlists *execlists = + container_of(hrtimer, typeof(*execlists), preempt_timer); + + GEM_TRACE("%s\n", + container_of(execlists, + struct intel_engine_cs, + execlists)->name); + + if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT)) + return HRTIMER_NORESTART; + + queue_work(system_highpri_wq, &execlists->preempt_reset); + return HRTIMER_NORESTART; +} + +static void preempt_reset(struct work_struct *work) +{ + struct intel_engine_execlists *execlists = + container_of(work, typeof(*execlists), preempt_reset); + struct intel_engine_cs *engine = + container_of(execlists, struct intel_engine_cs, execlists); + + GEM_TRACE("%s\n", engine->name); + + tasklet_disable(&execlists->tasklet); + + execlists->tasklet.func(execlists->tasklet.data); + + if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT)) + i915_handle_error(engine->i915, BIT(engine->id), 0, + "preemption time out on %s", engine->name); + + tasklet_enable(&execlists->tasklet); +} + static void complete_preempt_context(struct intel_engine_execlists *execlists) { GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); + hrtimer_try_to_cancel(&execlists->preempt_timer); + execlists_cancel_port_requests(execlists); execlists_unwind_incomplete_requests(execlists); @@ -722,6 +762,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) kmem_cache_free(engine->i915->priorities, p); } done: + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); execlists->queue_priority = port != execlists->port ? rq_prio(last) : INT_MIN; execlists->first = rb; @@ -1099,16 +1140,38 @@ static void queue_request(struct intel_engine_cs *engine, list_add_tail(&pt->link, &lookup_priolist(engine, pt, prio)->requests); } -static void __submit_queue(struct intel_engine_cs *engine, int prio) +static void __submit_queue(struct intel_engine_cs *engine, + int prio, unsigned int timeout) { - engine->execlists.queue_priority = prio; - tasklet_hi_schedule(&engine->execlists.tasklet); + struct intel_engine_execlists * const execlists = &engine->execlists; + int old = execlists->queue_priority; + + GEM_TRACE("%s prio=%d (previous=%d)\n", engine->name, prio, old); + + i
[Intel-gfx] Reset from within timeout for preemption Qos
Fleshed out the reset from within the timer context (hardirq) to the point where it at least passes selftests... Not that CI even likes the sanitycheck at the moment. -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/17] drm/i915/execlists: Track begin/end of execlists submission sequences
We would like to start doing some bookkeeping at the beginning, between contexts and at the end of execlists submission. We already mark the beginning and end using EXECLISTS_ACTIVE_USER, to provide an indication when the HW is idle. This give us a pair of sequence points we can then expand on for further bookkeeping. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Francisco Jerez --- drivers/gpu/drm/i915/intel_lrc.c| 42 - drivers/gpu/drm/i915/intel_ringbuffer.h | 11 - 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f60b61bf8b3b..2d2d33becce3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -374,6 +374,19 @@ execlists_context_status_change(struct i915_request *rq, unsigned long status) status, rq); } +static inline void +execlists_user_begin(struct intel_engine_execlists *execlists, +const struct execlist_port *port) +{ + execlists_set_active_once(execlists, EXECLISTS_ACTIVE_USER); +} + +static inline void +execlists_user_end(struct intel_engine_execlists *execlists) +{ + execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); +} + static inline void execlists_context_schedule_in(struct i915_request *rq) { @@ -711,7 +724,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) spin_unlock_irq(&engine->timeline->lock); if (submit) { - execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); + execlists_user_begin(execlists, execlists->port); execlists_submit_ports(engine); } @@ -742,7 +755,7 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) port++; } - execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); + execlists_user_end(execlists); } static void clear_gtiir(struct intel_engine_cs *engine) @@ -873,7 +886,7 @@ static void execlists_submission_tasklet(unsigned long data) { struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; - struct execlist_port * const port = execlists->port; + struct execlist_port *port = execlists->port; struct drm_i915_private *dev_priv = engine->i915; bool fw = false; @@ -1012,9 +1025,19 @@ static void execlists_submission_tasklet(unsigned long data) GEM_BUG_ON(count == 0); if (--count == 0) { + /* +* On the final event corresponding to the +* submission of this context, we expect either +* an element-switch event or a completion +* event (and on completion, the active-idle +* marker). No more preemptions, lite-restore +* or otherwise +*/ GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); GEM_BUG_ON(port_isset(&port[1]) && !(status & GEN8_CTX_STATUS_ELEMENT_SWITCH)); + GEM_BUG_ON(!port_isset(&port[1]) && + !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); GEM_BUG_ON(!i915_request_completed(rq)); execlists_context_schedule_out(rq); trace_i915_request_out(rq); @@ -1023,17 +1046,14 @@ static void execlists_submission_tasklet(unsigned long data) GEM_TRACE("%s completed ctx=%d\n", engine->name, port->context_id); - execlists_port_complete(execlists, port); + port = execlists_port_complete(execlists, port); + if (port_isset(port)) + execlists_user_begin(execlists, port); + else + execlists_user_end(execlists); } else { port_set(port, port_pack(rq, count)); } - - /* After the final element, the hw should be idle */ - GEM_BUG_ON(port_count(port) == 0 && - !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); - if (port_count(port) == 0) - execlists_clear_active(execlists, - EXECLISTS_ACTIVE_USER); } if (head != execlists->csb_head) {
[Intel-gfx] [PATCH 03/17] drm/i915/execlists: Refactor out complete_preempt_context()
As a complement to inject_preempt_context(), follow up with the function to handle its completion. This will be useful should we wish to extend the duties of the preempt-context for execlists. v2: And do the same for the guc. Signed-off-by: Chris Wilson Cc: Jeff McGee Cc: Michał Winiarski Reviewed-by: Jeff McGee #v1 --- drivers/gpu/drm/i915/intel_guc_submission.c | 26 +- drivers/gpu/drm/i915/intel_lrc.c| 23 +-- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 207cda062626..ef2e29959c5b 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -621,6 +621,21 @@ static void wait_for_guc_preempt_report(struct intel_engine_cs *engine) report->report_return_status = INTEL_GUC_REPORT_STATUS_UNKNOWN; } +static void complete_preempt_context(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists *execlists = &engine->execlists; + + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + + execlists_cancel_port_requests(execlists); + execlists_unwind_incomplete_requests(execlists); + + wait_for_guc_preempt_report(engine); + intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0); + + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); +} + /** * guc_submit() - Submit commands through GuC * @engine: engine associated with the commands @@ -762,15 +777,8 @@ static void guc_submission_tasklet(unsigned long data) if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) && intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) == - GUC_PREEMPT_FINISHED) { - execlists_cancel_port_requests(&engine->execlists); - execlists_unwind_incomplete_requests(execlists); - - wait_for_guc_preempt_report(engine); - - execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); - intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0); - } + GUC_PREEMPT_FINISHED) + complete_preempt_context(engine); if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)) guc_dequeue(engine); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a3fd9683f9d1..51e930323626 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -545,8 +545,18 @@ static void inject_preempt_context(struct intel_engine_cs *engine) if (execlists->ctrl_reg) writel(EL_CTRL_LOAD, execlists->ctrl_reg); - execlists_clear_active(&engine->execlists, EXECLISTS_ACTIVE_HWACK); - execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK); + execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); +} + +static void complete_preempt_context(struct intel_engine_execlists *execlists) +{ + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + + execlists_cancel_port_requests(execlists); + execlists_unwind_incomplete_requests(execlists); + + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } static void execlists_dequeue(struct intel_engine_cs *engine) @@ -994,14 +1004,7 @@ static void execlists_submission_tasklet(unsigned long data) if (status & GEN8_CTX_STATUS_COMPLETE && buf[2*head + 1] == execlists->preempt_complete_status) { GEM_TRACE("%s preempt-idle\n", engine->name); - - execlists_cancel_port_requests(execlists); - execlists_unwind_incomplete_requests(execlists); - - GEM_BUG_ON(!execlists_is_active(execlists, - EXECLISTS_ACTIVE_PREEMPT)); - execlists_clear_active(execlists, - EXECLISTS_ACTIVE_PREEMPT); + complete_preempt_context(execlists); continue; } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 15/17] drm/i915/preemption: Select timeout when scheduling
The choice of preemption timeout is determined by the context from which we trigger the preemption, as such allow the caller to specify the desired timeout. Effectively the other choice would be to use the shortest timeout along the dependency chain. However, given that we would have already triggered preemption for the dependency chain, we can assume that no preemption along that chain is more important than the current request, ergo we need only consider the current timeout. Realising this, we can then pass control of the preemption timeout to the caller for greater flexibility. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c| 2 +- drivers/gpu/drm/i915/i915_request.c| 2 +- drivers/gpu/drm/i915/intel_lrc.c | 5 +- drivers/gpu/drm/i915/intel_ringbuffer.h| 6 +- drivers/gpu/drm/i915/selftests/intel_lrc.c | 106 - 5 files changed, 114 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a866fe304de1..a860d501134e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -482,7 +482,7 @@ static void __fence_set_priority(struct dma_fence *fence, int prio) rcu_read_lock(); if (engine->schedule) - engine->schedule(rq, prio); + engine->schedule(rq, prio, 0); rcu_read_unlock(); } diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 585242831974..cdda3ebd51e2 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1108,7 +1108,7 @@ void __i915_request_add(struct i915_request *request, bool flush_caches) */ rcu_read_lock(); if (engine->schedule) - engine->schedule(request, request->ctx->priority); + engine->schedule(request, request->ctx->priority, 0); rcu_read_unlock(); local_bh_disable(); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index dfbf0913f14e..63f09128e5ec 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1240,7 +1240,8 @@ pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked) return engine; } -static void execlists_schedule(struct i915_request *request, int prio) +static void execlists_schedule(struct i915_request *request, + int prio, unsigned int timeout) { struct intel_engine_cs *engine; struct i915_dependency *dep, *p; @@ -1336,7 +1337,7 @@ static void execlists_schedule(struct i915_request *request, int prio) if (prio > engine->execlists.queue_priority && i915_sw_fence_done(&pt_to_request(pt)->submit)) - __submit_queue(engine, prio, 0); + __submit_queue(engine, prio, timeout); } spin_unlock_irq(&engine->timeline->lock); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 80c303bb54c8..1e85123534a8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -463,13 +463,15 @@ struct intel_engine_cs { */ void(*submit_request)(struct i915_request *rq); - /* Call when the priority on a request has changed and it and its + /* +* Call when the priority on a request has changed and it and its * dependencies may need rescheduling. Note the request itself may * not be ready to run! * * Called under the struct_mutex. */ - void(*schedule)(struct i915_request *request, int priority); + void(*schedule)(struct i915_request *request, + int priority, unsigned int timeout); /* * Cancel all requests on the hardware, or queued for execution. diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 626acf46f65e..46d13cd66e44 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -450,7 +450,7 @@ static int live_late_preempt(void *arg) goto err_wedged; } - engine->schedule(rq, I915_PRIORITY_MAX); + engine->schedule(rq, I915_PRIORITY_MAX, 0); if (!wait_for_spinner(&spin_hi, rq)) { pr_err("High priority context failed to preempt the low priority context\n"); @@ -673,6 +673,109 @@ static int live_preempt_reset(void *arg) return err; } +static int live_late_preempt_timeout(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx_hi, *ctx_lo; + struct spinner spin_hi, spin_lo; + struct intel_engine_cs *engine; + enum intel_engine_id id; +
[Intel-gfx] [PATCH 11/17] drm/i915: Be irqsafe inside reset
As we want to be able to call i915_reset_engine and co from a softirq or timer context, we need to be irqsafe at all timers. So we have to forgo the simple spin_lock_irq for the full spin_lock_irqsave. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8a6acb1d5ad3..a866fe304de1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3041,15 +3041,17 @@ i915_gem_reset_request(struct intel_engine_cs *engine, */ request = i915_gem_find_active_request(engine); if (request) { + unsigned long flags; + i915_gem_context_mark_innocent(request->ctx); dma_fence_set_error(&request->fence, -EAGAIN); /* Rewind the engine to replay the incomplete rq */ - spin_lock_irq(&engine->timeline->lock); + spin_lock_irqsave(&engine->timeline->lock, flags); request = list_prev_entry(request, link); if (&request->link == &engine->timeline->requests) request = NULL; - spin_unlock_irq(&engine->timeline->lock); + spin_unlock_irqrestore(&engine->timeline->lock, flags); } } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 17/17] drm/i915: Allow user control over preempt timeout on their important context
EGL_NV_realtime_priority? Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_context.c| 22 drivers/gpu/drm/i915/i915_gem_context.h| 13 + drivers/gpu/drm/i915/i915_request.c| 8 ++- drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/selftests/intel_lrc.c | 85 ++ include/uapi/drm/i915_drm.h| 12 + 6 files changed, 139 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5cfac0255758..dfb0a2b698c3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -749,6 +749,15 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_PRIORITY: args->value = ctx->priority; break; + case I915_CONTEXT_PARAM_PREEMPT_TIMEOUT: + if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION)) + ret = -ENODEV; + else if (args->size) + ret = -EINVAL; + else + args->value = ctx->preempt_timeout; + break; + default: ret = -EINVAL; break; @@ -824,6 +833,19 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, } break; + case I915_CONTEXT_PARAM_PREEMPT_TIMEOUT: + if (args->size) + ret = -EINVAL; + else if (args->value >= NSEC_PER_SEC) + ret = -EINVAL; + else if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION)) + ret = -ENODEV; + else if (args->value && !capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else + ctx->preempt_timeout = args->value; + break; + default: ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index 7854262ddfd9..74d4cadd729e 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -150,6 +150,19 @@ struct i915_gem_context { */ int priority; + /** +* @preempt_timeout: QoS guarantee for the high priority context +* +* Some clients need a guarantee that they will start executing +* within a certain window, even at the expense of others. This entails +* that if a preemption request is not honoured by the active context +* within the timeout, we will reset the GPU to evict the hog and +* run the high priority context instead. +* +* Timeout is stored in nanoseconds; exclusive max of 1s. +*/ + u32 preempt_timeout; + /** ggtt_offset_bias: placement restriction for context objects */ u32 ggtt_offset_bias; diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index cdda3ebd51e2..eae807e56723 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1107,8 +1107,12 @@ void __i915_request_add(struct i915_request *request, bool flush_caches) * run at the earliest possible convenience. */ rcu_read_lock(); - if (engine->schedule) - engine->schedule(request, request->ctx->priority, 0); + if (engine->schedule) { + unsigned int timeout = request->ctx->preempt_timeout; + int priority = request->ctx->priority; + + engine->schedule(request, priority, timeout); + } rcu_read_unlock(); local_bh_disable(); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 63f09128e5ec..3e65357d1d3f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1212,7 +1212,7 @@ static void execlists_submit_request(struct i915_request *request) spin_lock_irqsave(&engine->timeline->lock, flags); queue_request(engine, &request->priotree, rq_prio(request)); - submit_queue(engine, rq_prio(request), 0); + submit_queue(engine, rq_prio(request), request->ctx->preempt_timeout); GEM_BUG_ON(!engine->execlists.first); GEM_BUG_ON(list_empty(&request->priotree.link)); diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 46d13cd66e44..bc24961f38f8 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -776,6 +776,90 @@ static int live_late_preempt_timeout(void *arg) goto err_ctx_lo; } +static int live_context_preempt_timeout(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx_hi, *ctx_
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences
== Series Details == Series: series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences URL : https://patchwork.freedesktop.org/series/40927/ State : warning == Summary == $ dim checkpatch origin/drm-tip 0a86b9f594fb drm/i915/execlists: Track begin/end of execlists submission sequences 577684ae80f3 drm/i915/execlists: Set queue priority from secondary port -:25: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line) #25: References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") -:25: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("")' - ie: 'commit f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports")' #25: References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") total: 1 errors, 1 warnings, 0 checks, 9 lines checked fe156263d8b1 drm/i915/execlists: Refactor out complete_preempt_context() 7be12bc10a20 drm/i915: Move engine reset prepare/finish to backends 969d8ded5eba drm/i915: Split execlists/guc reset prepartions d5c288d4bf37 drm/i915/execlists: Flush pending preemption events during reset -:69: WARNING:LONG_LINE: line over 100 characters #69: FILE: drivers/gpu/drm/i915/intel_lrc.c:907: + (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); -:87: WARNING:LONG_LINE: line over 100 characters #87: FILE: drivers/gpu/drm/i915/intel_lrc.c:921: + head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); -:104: WARNING:LONG_LINE: line over 100 characters #104: FILE: drivers/gpu/drm/i915/intel_lrc.c:935: + head, GEN8_CSB_READ_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?", -:105: WARNING:LONG_LINE: line over 100 characters #105: FILE: drivers/gpu/drm/i915/intel_lrc.c:936: + tail, GEN8_CSB_WRITE_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?"); total: 0 errors, 4 warnings, 0 checks, 192 lines checked cf783aa12414 drm/i915/selftests: Add basic sanitychecks for execlists -:43: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating? #43: new file mode 100644 -:119: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV) #119: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:72: + return hws->node.start + offset_in_page(sizeof(u32)*rq->fence.context); ^ -:247: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'W' - possible side-effects? #247: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:200: +#define wedge_on_timeout(W, DEV, TIMEOUT) \ + for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \ +(W)->i915; \ +__fini_wedge((W))) total: 0 errors, 1 warnings, 2 checks, 511 lines checked 5a9c6a2ad3b8 drm/i915/breadcrumbs: Keep the fake irq armed across reset eecceca4efe5 drm/i915: Combine tasklet_kill and tasklet_disable -:39: WARNING:MEMORY_BARRIER: memory barrier without comment #39: FILE: drivers/gpu/drm/i915/intel_lrc.c:1755: + smp_mb(); total: 0 errors, 1 warnings, 0 checks, 26 lines checked afceb077b401 drm/i915: Stop parking the signaler around reset -:13: WARNING:TYPO_SPELLING: 'choosen' may be misspelled - perhaps 'chosen'? #13: advancing so that the GPU doesn't emit the breadcrumb for our choosen total: 0 errors, 1 warnings, 0 checks, 85 lines checked 17205a44c23d drm/i915: Be irqsafe inside reset 428fcef9ca7a drm/i915: Allow init_breadcrumbs to be used from irq context 7c900d2a6154 drm/i915/execlists: Force preemption via reset on timeout -:228: ERROR:SPACING: spaces required around that '=' (ctx:VxW) #228: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:508: + ctx= kernel_context(i915); ^ total: 1 errors, 0 warnings, 0 checks, 241 lines checked aac0236c4b8d drm/i915/execlists: Try preempt-reset from softirq context -:115: ERROR:SPACING: spaces required around that '=' (ctx:VxW) #115: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:593: + ctx= kernel_context(i915); ^ total: 1 errors, 0 warnings, 0 checks, 176 lines checked 4383544ed9ef drm/i915/preemption: Select timeout when scheduling 74b8058ff743 drm/i915: Use a preemption timeout to enforce interactivity f21a994c5239 drm/i915: Allow user control over preempt timeout on their important context ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences
== Series Details == Series: series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences URL : https://patchwork.freedesktop.org/series/40927/ State : failure == Summary == Series 40927v1 series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences https://patchwork.freedesktop.org/api/1.0/series/40927/revisions/1/mbox/ Possible new issues: Test kms_flip: Subgroup basic-plain-flip: pass -> INCOMPLETE (fi-cnl-y3) Known issues: Test kms_pipe_crc_basic: Subgroup suspend-read-crc-pipe-b: pass -> INCOMPLETE (fi-snb-2520m) fdo#103713 fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713 fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:431s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:444s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:380s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:538s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:296s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:520s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:514s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:521s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:511s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:412s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:560s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:512s fi-cnl-y3total:219 pass:198 dwarn:0 dfail:0 fail:0 skip:20 fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:423s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:317s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:535s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:403s fi-ilk-650 total:285 pass:225 dwarn:0 dfail:0 fail:0 skip:60 time:420s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:471s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:428s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:474s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:473s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:507s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:656s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:442s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:527s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:500s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:507s fi-skl-guc total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:431s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:445s fi-snb-2520m total:242 pass:208 dwarn:0 dfail:0 fail:0 skip:33 fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:400s Blacklisted hosts: fi-cnl-psr total:285 pass:256 dwarn:3 dfail:0 fail:0 skip:26 time:541s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:483s 335ef9849310af26d65c54f7d2d2e9dcbce238b9 drm-tip: 2018y-03m-30d-09h-08m-40s UTC integration manifest f21a994c5239 drm/i915: Allow user control over preempt timeout on their important context 74b8058ff743 drm/i915: Use a preemption timeout to enforce interactivity 4383544ed9ef drm/i915/preemption: Select timeout when scheduling aac0236c4b8d drm/i915/execlists: Try preempt-reset from softirq context 7c900d2a6154 drm/i915/execlists: Force preemption via reset on timeout 428fcef9ca7a drm/i915: Allow init_breadcrumbs to be used from irq context 17205a44c23d drm/i915: Be irqsafe inside reset afceb077b401 drm/i915: Stop parking the signaler around reset eecceca4efe5 drm/i915: Combine tasklet_kill and tasklet_disable 5a9c6a2ad3b8 drm/i915/breadcrumbs: Keep the fake irq armed across reset cf783aa12414 drm/i915/selftests: Add basic sanitychecks for execlists d5c288d4bf37 drm/i915/execlists: Flush pending preemption events during reset 969d8ded5eba drm/i915: Split execlists/guc reset prepartions 7be12bc10a20 drm/i915: Move engine reset prepare/finish to backends fe156263d8b1 drm/i915/execlists: Refactor out complete_preempt_context() 577684ae80f3 drm/i915/execlists: Set queue priority from secondary port 0a86b9f594fb drm/i915/execlists: Track begin/end of execlists submissio
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences
== Series Details == Series: series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences URL : https://patchwork.freedesktop.org/series/40927/ State : warning == Summary == $ dim checkpatch origin/drm-tip d71000599823 drm/i915/execlists: Track begin/end of execlists submission sequences 934e303733f6 drm/i915/execlists: Set queue priority from secondary port -:25: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line) #25: References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") -:25: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("")' - ie: 'commit f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports")' #25: References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") total: 1 errors, 1 warnings, 0 checks, 9 lines checked 06aa4edeb023 drm/i915/execlists: Refactor out complete_preempt_context() 7150789d6e56 drm/i915: Move engine reset prepare/finish to backends 25b87d182879 drm/i915: Split execlists/guc reset prepartions a46f451f9827 drm/i915/execlists: Flush pending preemption events during reset -:69: WARNING:LONG_LINE: line over 100 characters #69: FILE: drivers/gpu/drm/i915/intel_lrc.c:907: + (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); -:87: WARNING:LONG_LINE: line over 100 characters #87: FILE: drivers/gpu/drm/i915/intel_lrc.c:921: + head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); -:104: WARNING:LONG_LINE: line over 100 characters #104: FILE: drivers/gpu/drm/i915/intel_lrc.c:935: + head, GEN8_CSB_READ_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?", -:105: WARNING:LONG_LINE: line over 100 characters #105: FILE: drivers/gpu/drm/i915/intel_lrc.c:936: + tail, GEN8_CSB_WRITE_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?"); total: 0 errors, 4 warnings, 0 checks, 192 lines checked 55488482 drm/i915/selftests: Add basic sanitychecks for execlists -:43: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating? #43: new file mode 100644 -:119: CHECK:SPACING: spaces preferred around that '*' (ctx:VxV) #119: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:72: + return hws->node.start + offset_in_page(sizeof(u32)*rq->fence.context); ^ -:247: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'W' - possible side-effects? #247: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:200: +#define wedge_on_timeout(W, DEV, TIMEOUT) \ + for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \ +(W)->i915; \ +__fini_wedge((W))) total: 0 errors, 1 warnings, 2 checks, 511 lines checked 165feb53f995 drm/i915/breadcrumbs: Keep the fake irq armed across reset 13708e4e6f94 drm/i915: Combine tasklet_kill and tasklet_disable -:39: WARNING:MEMORY_BARRIER: memory barrier without comment #39: FILE: drivers/gpu/drm/i915/intel_lrc.c:1755: + smp_mb(); total: 0 errors, 1 warnings, 0 checks, 26 lines checked 435c7f3e4181 drm/i915: Stop parking the signaler around reset -:13: WARNING:TYPO_SPELLING: 'choosen' may be misspelled - perhaps 'chosen'? #13: advancing so that the GPU doesn't emit the breadcrumb for our choosen total: 0 errors, 1 warnings, 0 checks, 85 lines checked b7b11d47f57b drm/i915: Be irqsafe inside reset 28278ff2c649 drm/i915: Allow init_breadcrumbs to be used from irq context b9c1f591cc6b drm/i915/execlists: Force preemption via reset on timeout -:228: ERROR:SPACING: spaces required around that '=' (ctx:VxW) #228: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:508: + ctx= kernel_context(i915); ^ total: 1 errors, 0 warnings, 0 checks, 241 lines checked 1df46bdfe4a3 drm/i915/execlists: Try preempt-reset from softirq context -:115: ERROR:SPACING: spaces required around that '=' (ctx:VxW) #115: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:593: + ctx= kernel_context(i915); ^ total: 1 errors, 0 warnings, 0 checks, 176 lines checked 57ea892580e5 drm/i915/preemption: Select timeout when scheduling c9542a8112fd drm/i915: Use a preemption timeout to enforce interactivity b742993888d6 drm/i915: Allow user control over preempt timeout on their important context ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences
== Series Details == Series: series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences URL : https://patchwork.freedesktop.org/series/40927/ State : success == Summary == Series 40927v1 series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences https://patchwork.freedesktop.org/api/1.0/series/40927/revisions/1/mbox/ Known issues: Test gem_exec_suspend: Subgroup basic-s4-devices: pass -> DMESG-WARN (fi-kbl-7500u) fdo#105128 fdo#105128 https://bugs.freedesktop.org/show_bug.cgi?id=105128 fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:432s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:440s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:379s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:545s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:296s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:513s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:518s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:518s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:507s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:411s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:561s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:509s fi-cnl-y3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:583s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:428s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:315s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:537s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:403s fi-ilk-650 total:285 pass:225 dwarn:0 dfail:0 fail:0 skip:60 time:419s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:468s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:434s fi-kbl-7500u total:285 pass:259 dwarn:2 dfail:0 fail:0 skip:24 time:472s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:461s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:507s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:658s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:437s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:531s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:500s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:489s fi-skl-guc total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:431s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:446s fi-snb-2520m total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:574s fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:398s Blacklisted hosts: fi-cnl-psr total:285 pass:256 dwarn:3 dfail:0 fail:0 skip:26 time:552s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:486s 335ef9849310af26d65c54f7d2d2e9dcbce238b9 drm-tip: 2018y-03m-30d-09h-08m-40s UTC integration manifest b742993888d6 drm/i915: Allow user control over preempt timeout on their important context c9542a8112fd drm/i915: Use a preemption timeout to enforce interactivity 57ea892580e5 drm/i915/preemption: Select timeout when scheduling 1df46bdfe4a3 drm/i915/execlists: Try preempt-reset from softirq context b9c1f591cc6b drm/i915/execlists: Force preemption via reset on timeout 28278ff2c649 drm/i915: Allow init_breadcrumbs to be used from irq context b7b11d47f57b drm/i915: Be irqsafe inside reset 435c7f3e4181 drm/i915: Stop parking the signaler around reset 13708e4e6f94 drm/i915: Combine tasklet_kill and tasklet_disable 165feb53f995 drm/i915/breadcrumbs: Keep the fake irq armed across reset 55488482 drm/i915/selftests: Add basic sanitychecks for execlists a46f451f9827 drm/i915/execlists: Flush pending preemption events during reset 25b87d182879 drm/i915: Split execlists/guc reset prepartions 7150789d6e56 drm/i915: Move engine reset prepare/finish to backends 06aa4edeb023 drm/i915/execlists: Refactor out complete_preempt_context() 934e303733f6 drm/i915/execlists: Set queue priority from secondary port d71000599823 drm/i915/execlists: Track begin/end of execlists submission sequences == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8546/issues.html _
[Intel-gfx] [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
Before this commit the WaSkipStolenMemoryFirstPage workaround code was skipping the first 4k by passing 4096 as start of the address range passed to drm_mm_init(). This means that calling drm_mm_reserve_node() to try and reserve the firmware framebuffer so that we can inherit it would always fail, as the firmware framebuffer starts at address 0. Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on everything >= gen8") says in its commit message: "This is confirmed to fix Skylake screen flickering issues (probably caused by the fact that we initialized a ring in the first page of stolen, but I didn't 100% confirm this theory)." Which suggests that it is safe to use the first page for a linear framebuffer as the firmware is doing. This commit always passes 0 as start to drm_mm_init() and works around WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range() by insuring the start address passed by to drm_mm_insert_node_in_range() is always 4k or more. All entry points to i915_gem_stolen.c go through i915_gem_stolen_insert_node_in_range(), so that any newly allocated objects such as ring-buffers will not be allocated in the first 4k. The one exception is i915_gem_object_create_stolen_for_preallocated() which directly calls drm_mm_reserve_node() which now will be able to use the first 4k. This fixes the i915 driver no longer being able to inherit the firmware framebuffer on gen8+, which fixes the video output changing from the vendor logo to a black screen as soon as the i915 driver is loaded (on systems without fbcon). Signed-off-by: Hans de Goede --- drivers/gpu/drm/i915/i915_gem_stolen.c | 15 ++- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index af915d041281..ad949cc30928 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -51,6 +51,10 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv, if (!drm_mm_initialized(&dev_priv->mm.stolen)) return -ENODEV; + /* WaSkipStolenMemoryFirstPage:bdw+ */ + if (INTEL_GEN(dev_priv) >= 8 && start < 4096) + start = 4096; + mutex_lock(&dev_priv->mm.stolen_lock); ret = drm_mm_insert_node_in_range(&dev_priv->mm.stolen, node, size, alignment, 0, @@ -343,7 +347,6 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv) { resource_size_t reserved_base, stolen_top; resource_size_t reserved_total, reserved_size; - resource_size_t stolen_usable_start; mutex_init(&dev_priv->mm.stolen_lock); @@ -435,17 +438,11 @@ int i915_gem_init_stolen(struct drm_i915_private *dev_priv) (u64)resource_size(&dev_priv->dsm) >> 10, ((u64)resource_size(&dev_priv->dsm) - reserved_total) >> 10); - stolen_usable_start = 0; - /* WaSkipStolenMemoryFirstPage:bdw+ */ - if (INTEL_GEN(dev_priv) >= 8) - stolen_usable_start = 4096; - dev_priv->stolen_usable_size = - resource_size(&dev_priv->dsm) - reserved_total - stolen_usable_start; + resource_size(&dev_priv->dsm) - reserved_total; /* Basic memrange allocator for stolen space. */ - drm_mm_init(&dev_priv->mm.stolen, stolen_usable_start, - dev_priv->stolen_usable_size); + drm_mm_init(&dev_priv->mm.stolen, 0, dev_priv->stolen_usable_size); return 0; } -- 2.17.0.rc2 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
Quoting Hans de Goede (2018-03-30 13:27:15) > Before this commit the WaSkipStolenMemoryFirstPage workaround code was > skipping the first 4k by passing 4096 as start of the address range passed > to drm_mm_init(). This means that calling drm_mm_reserve_node() to try and > reserve the firmware framebuffer so that we can inherit it would always > fail, as the firmware framebuffer starts at address 0. > > Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on > everything >= gen8") says in its commit message: "This is confirmed to fix > Skylake screen flickering issues (probably caused by the fact that we > initialized a ring in the first page of stolen, but I didn't 100% confirm > this theory)." > > Which suggests that it is safe to use the first page for a linear > framebuffer as the firmware is doing. > > This commit always passes 0 as start to drm_mm_init() and works around > WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range() > by insuring the start address passed by to drm_mm_insert_node_in_range() > is always 4k or more. All entry points to i915_gem_stolen.c go through > i915_gem_stolen_insert_node_in_range(), so that any newly allocated > objects such as ring-buffers will not be allocated in the first 4k. > > The one exception is i915_gem_object_create_stolen_for_preallocated() > which directly calls drm_mm_reserve_node() which now will be able to > use the first 4k. > > This fixes the i915 driver no longer being able to inherit the firmware > framebuffer on gen8+, which fixes the video output changing from the > vendor logo to a black screen as soon as the i915 driver is loaded > (on systems without fbcon). We've been told by the HW guys not to use the first page. (That's my understanding from every time this gets questioned.) -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences
== Series Details == Series: series starting with [01/17] drm/i915/execlists: Track begin/end of execlists submission sequences URL : https://patchwork.freedesktop.org/series/40927/ State : failure == Summary == Possible new issues: Test drv_selftest: Subgroup live_hangcheck: pass -> INCOMPLETE (shard-apl) Test gem_ctx_param: Subgroup invalid-param-get: pass -> FAIL (shard-apl) pass -> FAIL (shard-hsw) pass -> FAIL (shard-snb) Subgroup invalid-param-set: pass -> FAIL (shard-apl) pass -> FAIL (shard-hsw) pass -> FAIL (shard-snb) Known issues: Test kms_cursor_legacy: Subgroup flip-vs-cursor-toggle: pass -> FAIL (shard-hsw) fdo#102670 Test kms_flip: Subgroup 2x-dpms-vs-vblank-race: fail -> PASS (shard-hsw) fdo#103060 Subgroup 2x-flip-vs-expired-vblank-interruptible: fail -> PASS (shard-hsw) fdo#102887 Subgroup flip-vs-blocking-wf-vblank: fail -> PASS (shard-hsw) fdo#100368 Subgroup flip-vs-panning-vs-hang-interruptible: dmesg-warn -> PASS (shard-snb) fdo#103821 Test kms_plane: Subgroup plane-panning-bottom-right-suspend-pipe-c-planes: pass -> INCOMPLETE (shard-hsw) fdo#103375 Test kms_sysfs_edid_timing: pass -> WARN (shard-apl) fdo#100047 fdo#102670 https://bugs.freedesktop.org/show_bug.cgi?id=102670 fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060 fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887 fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368 fdo#103821 https://bugs.freedesktop.org/show_bug.cgi?id=103821 fdo#103375 https://bugs.freedesktop.org/show_bug.cgi?id=103375 fdo#100047 https://bugs.freedesktop.org/show_bug.cgi?id=100047 shard-apltotal:3477 pass:1810 dwarn:1 dfail:0 fail:9 skip:1655 time:12396s shard-hswtotal:3494 pass:1778 dwarn:1 dfail:0 fail:4 skip:1709 time:10821s shard-snbtotal:3496 pass:1373 dwarn:1 dfail:0 fail:5 skip:2117 time:6993s Blacklisted hosts: shard-kbltotal:3496 pass:1929 dwarn:29 dfail:1 fail:9 skip:1528 time:9218s == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8546/shards.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
Hi, On 30-03-18 14:30, Chris Wilson wrote: Quoting Hans de Goede (2018-03-30 13:27:15) Before this commit the WaSkipStolenMemoryFirstPage workaround code was skipping the first 4k by passing 4096 as start of the address range passed to drm_mm_init(). This means that calling drm_mm_reserve_node() to try and reserve the firmware framebuffer so that we can inherit it would always fail, as the firmware framebuffer starts at address 0. Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on everything >= gen8") says in its commit message: "This is confirmed to fix Skylake screen flickering issues (probably caused by the fact that we initialized a ring in the first page of stolen, but I didn't 100% confirm this theory)." Which suggests that it is safe to use the first page for a linear framebuffer as the firmware is doing. This commit always passes 0 as start to drm_mm_init() and works around WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range() by insuring the start address passed by to drm_mm_insert_node_in_range() is always 4k or more. All entry points to i915_gem_stolen.c go through i915_gem_stolen_insert_node_in_range(), so that any newly allocated objects such as ring-buffers will not be allocated in the first 4k. The one exception is i915_gem_object_create_stolen_for_preallocated() which directly calls drm_mm_reserve_node() which now will be able to use the first 4k. This fixes the i915 driver no longer being able to inherit the firmware framebuffer on gen8+, which fixes the video output changing from the vendor logo to a black screen as soon as the i915 driver is loaded (on systems without fbcon). We've been told by the HW guys not to use the first page. (That's my understanding from every time this gets questioned.) Yet the GOP is happily using the first page. I think we may need to make a difference here between the GPU not using the first page and the display engine/pipeline not using the first page. Note that my patch only influences the inheriting of the initial framebuffer as allocated by the GOP. It does not influence any other allocations from the reserved range, those will still all avoid the first page. Without this patch fastboot / flickerfree support is essentially broken on any gen8+ hardware given that one of the goals of atomic is to be able to do flickerfree transitions I think that this warrants a closer look then just simply saying never use the first page. Regards, Hans ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v12 01/17] drm/i915/guc/slpc: Add SLPC control to enable_guc modparam
On Fri, 30 Mar 2018 10:31:46 +0200, Sagar Arun Kamble wrote: From: Tom O'Rourke GuC is currently being used for submission and HuC authentication. Choices can be configured through enable_guc modparam. GuC SLPC is GT Power and Performance management feature in GuC. Add another option to enable_guc modparam to control SLPC. v1: Add early call to sanitize enable_guc_slpc in intel_guc_ucode_init Remove sanitize enable_guc_slpc call before firmware version check is performed. (ChrisW) Version check is added in next patch and that will be done as part of slpc_enable_sanitize function in the next patch. (Sagar) Updated slpc option sanitize function call for platforms without GuC support. This was caught by CI BAT. v2: Changed parameter to dev_priv for HAS_SLPC macro. (David) Code indentation based on checkpatch. v3: Rebase. v4: Moved sanitization of SLPC option post GuC load. v5: Removed function intel_slpc_enabled. Planning to rely only on kernel parameter. Moved sanitization prior to GuC load to use the parameter during SLPC state setup during to GuC load. (Sagar) v6: Commit message update. Rebase. v7: Moved SLPC option sanitization to intel_uc_sanitize_options. v8: Clearing SLPC option on GuC load failure. Change moved from later patch. (Sagar) v9: s/enable_slpc/enable_guc_slpc. Rebase w.r.t modparam change. v10: Rebase. Separate modparam is not needed now that we maintain all options in single param enable_guc. Suggested-by: Paulo Zanoni Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_params.c | 5 +++-- drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_uc.c| 23 +++ drivers/gpu/drm/i915/intel_uc.h| 6 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 08108ce..40b799b 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -150,9 +150,10 @@ i915_param_named_unsafe(edp_vswing, int, 0400, "2=default swing(400mV))"); i915_param_named_unsafe(enable_guc, int, 0400, - "Enable GuC load for GuC submission and/or HuC load. " + "Enable GuC load for GuC submission and/or HuC load and/or GuC SLPC. " "Required functionality can be selected using bitmask values. " - "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load)"); + "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load, " + "4=GuC SLPC)"); Maybe to avoid later surprise, we should explicitly say that: + "4=GuC SLPC [requires GuC submission])"); i915_param_named(guc_log_level, int, 0400, "GuC firmware logging level. Requires GuC to be loaded. " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index c963603..2484925 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -32,6 +32,7 @@ struct drm_printer; #define ENABLE_GUC_SUBMISSION BIT(0) #define ENABLE_GUC_LOAD_HUCBIT(1) +#define ENABLE_GUC_SLPCBIT(2) #define I915_PARAMS_FOR_EACH(param) \ param(char *, vbt_firmware, NULL) \ diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 1cffaf7..0e4a97f 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -56,9 +56,15 @@ static int __get_platform_enable_guc(struct drm_i915_private *dev_priv) struct intel_uc_fw *huc_fw = &dev_priv->huc.fw; int enable_guc = 0; - /* Default is to enable GuC/HuC if we know their firmwares */ - if (intel_uc_fw_is_selected(guc_fw)) + /* +* Default is to enable GuC submission/SLPC/HuC if we know their +* firmwares +*/ + if (intel_uc_fw_is_selected(guc_fw)) { enable_guc |= ENABLE_GUC_SUBMISSION; + enable_guc |= ENABLE_GUC_SLPC; + } + if (intel_uc_fw_is_selected(huc_fw)) enable_guc |= ENABLE_GUC_LOAD_HUC; @@ -110,10 +116,11 @@ static void sanitize_options_early(struct drm_i915_private *dev_priv) if (i915_modparams.enable_guc < 0) i915_modparams.enable_guc = __get_platform_enable_guc(dev_priv); - DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n", + DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s slpc:%s)\n", i915_modparams.enable_guc, yesno(intel_uc_is_using_guc_submission()), -yesno(intel_uc_is_using_huc())); +yesno(intel_uc_is_using_huc()), +yesno(intel_uc_is_using_guc_slpc())); /* Verify GuC firmware availability */ if (intel_uc_is_using_guc
Re: [Intel-gfx] [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
Quoting Hans de Goede (2018-03-30 13:37:40) > Hi, > > On 30-03-18 14:30, Chris Wilson wrote: > > Quoting Hans de Goede (2018-03-30 13:27:15) > >> Before this commit the WaSkipStolenMemoryFirstPage workaround code was > >> skipping the first 4k by passing 4096 as start of the address range passed > >> to drm_mm_init(). This means that calling drm_mm_reserve_node() to try and > >> reserve the firmware framebuffer so that we can inherit it would always > >> fail, as the firmware framebuffer starts at address 0. > >> > >> Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on > >> everything >= gen8") says in its commit message: "This is confirmed to fix > >> Skylake screen flickering issues (probably caused by the fact that we > >> initialized a ring in the first page of stolen, but I didn't 100% confirm > >> this theory)." > >> > >> Which suggests that it is safe to use the first page for a linear > >> framebuffer as the firmware is doing. > >> > >> This commit always passes 0 as start to drm_mm_init() and works around > >> WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range() > >> by insuring the start address passed by to drm_mm_insert_node_in_range() > >> is always 4k or more. All entry points to i915_gem_stolen.c go through > >> i915_gem_stolen_insert_node_in_range(), so that any newly allocated > >> objects such as ring-buffers will not be allocated in the first 4k. > >> > >> The one exception is i915_gem_object_create_stolen_for_preallocated() > >> which directly calls drm_mm_reserve_node() which now will be able to > >> use the first 4k. > >> > >> This fixes the i915 driver no longer being able to inherit the firmware > >> framebuffer on gen8+, which fixes the video output changing from the > >> vendor logo to a black screen as soon as the i915 driver is loaded > >> (on systems without fbcon). > > > > We've been told by the HW guys not to use the first page. (That's my > > understanding from every time this gets questioned.) > > Yet the GOP is happily using the first page. I think we may need to make > a difference here between the GPU not using the first page and the > display engine/pipeline not using the first page. Note that my patch > only influences the inheriting of the initial framebuffer as allocated > by the GOP. It does not influence any other allocations from the > reserved range, those will still all avoid the first page. > > Without this patch fastboot / flickerfree support is essentially broken > on any gen8+ hardware given that one of the goals of atomic is to be > able to do flickerfree transitions I think that this warrants a closer > look then just simply saying never use the first page. The concern is what else (i.e. nothing that we allocated ourselves) that may be in the first page... -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
== Series Details == Series: drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers URL : https://patchwork.freedesktop.org/series/40929/ State : success == Summary == Series 40929v1 drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers https://patchwork.freedesktop.org/api/1.0/series/40929/revisions/1/mbox/ fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:429s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:443s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:380s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:533s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:295s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:518s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:511s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:518s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:508s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:408s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:558s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:518s fi-cnl-y3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:586s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:421s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:315s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:539s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:404s fi-ilk-650 total:285 pass:225 dwarn:0 dfail:0 fail:0 skip:60 time:423s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:470s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:429s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:470s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:460s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:509s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:658s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:442s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:533s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:500s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:509s fi-skl-guc total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:430s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:446s fi-snb-2520m total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:581s fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:402s Blacklisted hosts: fi-cnl-psr total:285 pass:254 dwarn:3 dfail:0 fail:2 skip:26 time:515s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:484s 335ef9849310af26d65c54f7d2d2e9dcbce238b9 drm-tip: 2018y-03m-30d-09h-08m-40s UTC integration manifest bfdc21d08f2b drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8547/issues.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH] drm/i915/selftests: Avoid repeatedly harming the same innocent context
We don't handle resetting the kernel context very well, or presumably any context executing its breadcrumb commands in the ring as opposed to the batchbuffer and flush. If we trigger a device reset twice in quick succession while the kernel context is executing, we may end up skipping the breadcrumb. This is really only a problem for the selftest as normally there is a large interlude between resets (hangcheck), or we focus on resetting just one engine and so avoid repeatedly resetting innocents. Something to try would be a preempt-to-idle to quiesce the engine before reset, so that innocent contexts would be spared the reset. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry --- drivers/gpu/drm/i915/i915_drv.c | 3 ++ drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 48 ++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d354627882e3..684060ed8db6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1886,6 +1886,8 @@ void i915_reset(struct drm_i915_private *i915) int ret; int i; + GEM_TRACE("flags=%lx\n", error->flags); + might_sleep(); lockdep_assert_held(&i915->drm.struct_mutex); GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags)); @@ -2016,6 +2018,7 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) struct i915_request *active_request; int ret; + GEM_TRACE("%s flags=%lx\n", engine->name, error->flags); GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags)); active_request = i915_gem_reset_prepare_engine(engine); diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 9e4e0ad62724..122a32e0a69d 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -979,6 +979,23 @@ static int igt_wait_reset(void *arg) return err; } +static int wait_for_others(struct drm_i915_private *i915, + struct intel_engine_cs *exclude) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + for_each_engine(engine, i915, id) { + if (engine == exclude) + continue; + + if (wait_for(intel_engine_is_idle(engine), 10)) + return -EIO; + } + + return 0; +} + static int igt_reset_queue(void *arg) { struct drm_i915_private *i915 = arg; @@ -1027,13 +1044,36 @@ static int igt_reset_queue(void *arg) i915_request_get(rq); __i915_request_add(rq, true); + /* +* XXX We don't handle resetting the kernel context +* very well. If we trigger a device reset twice in +* quick succession while the kernel context is +* executing, we may end up skipping the breadcrumb. +* This is really only a problem for the selftest as +* normally there is a large interlude between resets +* (hangcheck), or we focus on resetting just one +* engine and so avoid repeatedly resetting innocents. +*/ + err = wait_for_others(i915, engine); + if (err) { + pr_err("%s(%s): Failed to idle other inactive engines after device reset\n", + __func__, engine->name); + i915_request_put(rq); + i915_request_put(prev); + + GEM_TRACE_DUMP(); + i915_gem_set_wedged(i915); + goto fini; + } + if (!wait_for_hang(&h, prev)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", - __func__, prev->fence.seqno, hws_seqno(&h, prev)); - intel_engine_dump(prev->engine, &p, - "%s\n", prev->engine->name); + pr_err("%s(%s): Failed to start request %x, at %x\n", + __func__, engine->name, + prev->fence.seqno, hws_seqno(&h, prev)); + intel_engine_dump(engine, &p, + "%s\n", engine->name); i915_request_put(rq); i915_request_put(prev
Re: [Intel-gfx] [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
Hi, On 30-03-18 14:44, Chris Wilson wrote: Quoting Hans de Goede (2018-03-30 13:37:40) Hi, On 30-03-18 14:30, Chris Wilson wrote: Quoting Hans de Goede (2018-03-30 13:27:15) Before this commit the WaSkipStolenMemoryFirstPage workaround code was skipping the first 4k by passing 4096 as start of the address range passed to drm_mm_init(). This means that calling drm_mm_reserve_node() to try and reserve the firmware framebuffer so that we can inherit it would always fail, as the firmware framebuffer starts at address 0. Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on everything >= gen8") says in its commit message: "This is confirmed to fix Skylake screen flickering issues (probably caused by the fact that we initialized a ring in the first page of stolen, but I didn't 100% confirm this theory)." Which suggests that it is safe to use the first page for a linear framebuffer as the firmware is doing. This commit always passes 0 as start to drm_mm_init() and works around WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range() by insuring the start address passed by to drm_mm_insert_node_in_range() is always 4k or more. All entry points to i915_gem_stolen.c go through i915_gem_stolen_insert_node_in_range(), so that any newly allocated objects such as ring-buffers will not be allocated in the first 4k. The one exception is i915_gem_object_create_stolen_for_preallocated() which directly calls drm_mm_reserve_node() which now will be able to use the first 4k. This fixes the i915 driver no longer being able to inherit the firmware framebuffer on gen8+, which fixes the video output changing from the vendor logo to a black screen as soon as the i915 driver is loaded (on systems without fbcon). We've been told by the HW guys not to use the first page. (That's my understanding from every time this gets questioned.) Yet the GOP is happily using the first page. I think we may need to make a difference here between the GPU not using the first page and the display engine/pipeline not using the first page. Note that my patch only influences the inheriting of the initial framebuffer as allocated by the GOP. It does not influence any other allocations from the reserved range, those will still all avoid the first page. Without this patch fastboot / flickerfree support is essentially broken on any gen8+ hardware given that one of the goals of atomic is to be able to do flickerfree transitions I think that this warrants a closer look then just simply saying never use the first page. The concern is what else (i.e. nothing that we allocated ourselves) that may be in the first page... Given that the GOP has put its framebuffer there at least at boot there is nothing there, otherwise it would show up on the display. We have a whole bunch of code to inherit the BIOS fb in intel_display.c and AFAIK that code is there because this inheriting the BIOS fb is deemed an important feature. So I'm not happy at all with the handwavy best to not touch it answer I'm getting to this patch. Unless there are some clear answer from the hardware folks which specifically say we cannot put a framebuffer there (and then why is the GOP doing it?) then I believe that the best way forward here is to get various people to test with this patch and the best way to do that is probably to put it in next. Note I deliberately did not add a Cc stable. Regards, Hans ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/selftests: Avoid repeatedly harming the same innocent context
== Series Details == Series: drm/i915/selftests: Avoid repeatedly harming the same innocent context URL : https://patchwork.freedesktop.org/series/40941/ State : warning == Summary == $ dim checkpatch origin/drm-tip 477c0fa0c0b5 drm/i915/selftests: Avoid repeatedly harming the same innocent context -:57: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis #57: FILE: drivers/gpu/drm/i915/selftests/intel_hangcheck.c:983: +static int wait_for_others(struct drm_i915_private *i915, + struct intel_engine_cs *exclude) total: 0 errors, 0 warnings, 1 checks, 78 lines checked ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✓ Fi.CI.IGT: success for drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
== Series Details == Series: drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers URL : https://patchwork.freedesktop.org/series/40929/ State : success == Summary == Known issues: Test kms_flip: Subgroup 2x-dpms-vs-vblank-race: fail -> PASS (shard-hsw) fdo#103060 Subgroup 2x-flip-vs-expired-vblank-interruptible: fail -> PASS (shard-hsw) fdo#102887 Subgroup flip-vs-blocking-wf-vblank: fail -> PASS (shard-hsw) fdo#100368 +1 Subgroup flip-vs-panning-vs-hang-interruptible: dmesg-warn -> PASS (shard-snb) fdo#103821 Test kms_sysfs_edid_timing: pass -> WARN (shard-apl) fdo#100047 fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060 fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887 fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368 fdo#103821 https://bugs.freedesktop.org/show_bug.cgi?id=103821 fdo#100047 https://bugs.freedesktop.org/show_bug.cgi?id=100047 shard-apltotal:3495 pass:1831 dwarn:1 dfail:0 fail:7 skip:1655 time:12913s shard-hswtotal:3495 pass:1782 dwarn:1 dfail:0 fail:2 skip:1709 time:11419s shard-snbtotal:3495 pass:1374 dwarn:1 dfail:0 fail:3 skip:2117 time:6970s Blacklisted hosts: shard-kbltotal:3495 pass:1946 dwarn:12 dfail:0 fail:9 skip:1528 time:9154s == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8547/shards.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v12 05/17] drm/i915/guc/slpc: Add SLPC communication interfaces
On Fri, 30 Mar 2018 10:31:50 +0200, Sagar Arun Kamble wrote: Communication with SLPC is via Host to GuC interrupt through shared data and parameters. This patch defines the structure of shared data, parameters, data structure to be passed as input and received as output from SLPC. This patch also defines the events to be sent as input and status values output by GuC on processing SLPC events. SLPC shared data has details of SKU type, Slice count, IA Perf MSR values, SLPC state, Power source/plan, SLPC tasks status. Parameters allow overriding task control, frequency range etc. v1: fix whitespace (Sagar) v2-v3: Rebase. v4: Updated with GuC firmware v9. v5: Added definition of input and output data structures for SLPC events. Updated commit message. v6: Removed definition of host2guc_slpc. Will be added in the next patch that uses it. Commit subject update. Rebase. v7: Added definition of SLPC_RESET_FLAG_TDR_OCCURRED to be sent throgh SLPC reset in case of engine reset. Moved all Host/SLPC interfaces from later patches to this patch. Commit message update. v8: Updated value of SLPC_RESET_FLAG_TDR_OCCURRED. v9: Removed struct slpc_param, slpc_paramlist and corresponding defines. Will be added in later patches where they are used. v10: Rebase. Prepared separate header for SLPC firmware interface. Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_slpc.h | 2 + drivers/gpu/drm/i915/intel_guc_slpc_fwif.h | 211 + 2 files changed, 213 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_guc_slpc_fwif.h diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h index 66c76fe..81250c0 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/intel_guc_slpc.h @@ -6,6 +6,8 @@ #ifndef _INTEL_GUC_SLPC_H_ #define _INTEL_GUC_SLPC_H_ +#include Please use "" instead of <> + struct intel_guc_slpc { }; diff --git a/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h new file mode 100644 index 000..9400af4 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h @@ -0,0 +1,211 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2015-2018 Intel Corporation + */ +#ifndef _INTEL_GUC_SLPC_FWIF_H_ +#define _INTEL_GUC_SLPC_FWIF_H_ + +#include + +enum slpc_status { s/slpc_status/intel_guc_slpc_status + SLPC_STATUS_OK = 0, + SLPC_STATUS_ERROR = 1, + SLPC_STATUS_ILLEGAL_COMMAND = 2, + SLPC_STATUS_INVALID_ARGS = 3, + SLPC_STATUS_INVALID_PARAMS = 4, + SLPC_STATUS_INVALID_DATA = 5, + SLPC_STATUS_OUT_OF_RANGE = 6, + SLPC_STATUS_NOT_SUPPORTED = 7, + SLPC_STATUS_NOT_IMPLEMENTED = 8, + SLPC_STATUS_NO_DATA = 9, + SLPC_STATUS_EVENT_NOT_REGISTERED = 10, + SLPC_STATUS_REGISTER_LOCKED = 11, + SLPC_STATUS_TEMPORARILY_UNAVAILABLE = 12, + SLPC_STATUS_VALUE_ALREADY_SET = 13, + SLPC_STATUS_VALUE_ALREADY_UNSET = 14, + SLPC_STATUS_VALUE_NOT_CHANGED = 15, + SLPC_STATUS_MEMIO_ERROR = 16, + SLPC_STATUS_EVENT_QUEUED_REQ_DPC = 17, + SLPC_STATUS_EVENT_QUEUED_NOREQ_DPC = 18, + SLPC_STATUS_NO_EVENT_QUEUED = 19, + SLPC_STATUS_OUT_OF_SPACE = 20, + SLPC_STATUS_TIMEOUT = 21, + SLPC_STATUS_NO_LOCK = 22, + SLPC_STATUS_MAX s/SLPC_STATUS/INTEL_GUC_SLPC_STATUS +}; + +enum slpc_event_id { s/slpc_event_id/intel_guc_slpc_event + SLPC_EVENT_RESET = 0, + SLPC_EVENT_SHUTDOWN = 1, + SLPC_EVENT_PLATFORM_INFO_CHANGE = 2, + SLPC_EVENT_DISPLAY_MODE_CHANGE = 3, + SLPC_EVENT_FLIP_COMPLETE = 4, + SLPC_EVENT_QUERY_TASK_STATE = 5, + SLPC_EVENT_PARAMETER_SET = 6, + SLPC_EVENT_PARAMETER_UNSET = 7, s/SLPC_EVENT/INTEL_GUC_SLPC_EVENT +}; + +enum slpc_param_id { s/slpc_param_id/intel_guc_slpc_param + SLPC_PARAM_TASK_ENABLE_GTPERF = 0, + SLPC_PARAM_TASK_DISABLE_GTPERF = 1, + SLPC_PARAM_TASK_ENABLE_BALANCER = 2, + SLPC_PARAM_TASK_DISABLE_BALANCER = 3, + SLPC_PARAM_TASK_ENABLE_DCC = 4, + SLPC_PARAM_TASK_DISABLE_DCC = 5, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6, + SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7, + SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8, + SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9, + SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10, + SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11, + SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12, + SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13, + SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14, + SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15, + SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16, + SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17, +
[Intel-gfx] ✓ Fi.CI.BAT: success for drm/i915/selftests: Avoid repeatedly harming the same innocent context
== Series Details == Series: drm/i915/selftests: Avoid repeatedly harming the same innocent context URL : https://patchwork.freedesktop.org/series/40941/ State : success == Summary == Series 40941v1 drm/i915/selftests: Avoid repeatedly harming the same innocent context https://patchwork.freedesktop.org/api/1.0/series/40941/revisions/1/mbox/ Known issues: Test prime_vgem: Subgroup basic-fence-flip: pass -> FAIL (fi-ilk-650) fdo#104008 fdo#104008 https://bugs.freedesktop.org/show_bug.cgi?id=104008 fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:435s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:441s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:379s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:531s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:298s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:512s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:513s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:519s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:506s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:412s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:560s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:509s fi-cnl-y3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:589s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:426s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:316s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:533s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:402s fi-ilk-650 total:285 pass:224 dwarn:0 dfail:0 fail:1 skip:60 time:421s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:476s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:427s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:472s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:461s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:508s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:658s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:439s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:533s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:506s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:514s fi-skl-guc total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:430s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:447s fi-snb-2520m total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:581s fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:400s Blacklisted hosts: fi-cnl-psr total:285 pass:256 dwarn:3 dfail:0 fail:0 skip:26 time:532s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:486s 335ef9849310af26d65c54f7d2d2e9dcbce238b9 drm-tip: 2018y-03m-30d-09h-08m-40s UTC integration manifest 477c0fa0c0b5 drm/i915/selftests: Avoid repeatedly harming the same innocent context == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8548/issues.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] trace: Default to using trace_global_clock if sched_clock is unstable
On Thu, 29 Mar 2018 23:25:57 +0100 Chris Wilson wrote: > Across suspend, we may see a very large drift in timestamps if the sched > clock is unstable, prompting the global trace's ringbuffer code to warn > and suggest switching to the global clock. Preempt this request by > detecting when the sched clock is unstable (determined during > late_initcall) and automatically switching the default clock over to > trace_global_clock. > > This should prevent requiring user interaction to resolve warnings such > as: > > Delta way too big! 18446743856563626466 ts=18446744054496180323 write > stamp = 197932553857 > If you just came from a suspend/resume, > please switch to the trace global clock: > echo global > /sys/kernel/debug/tracing/trace_clock global clock has a much higher overhead than the local clock. I rather not have it automatically switch even when there's no stable TSC. That will be annoying to myself as I have boxes that this would switch on and I prefer to keep the local clock. One can also decide the clock with the kernel command line. Should we update that message to also say: Or set the global clock via the kernel command line with "trace_clock=global" ? -- Steve > > Signed-off-by: Chris Wilson > Cc: Steven Rostedt (VMware) > --- > kernel/trace/trace.c | 13 + > 1 file changed, 13 insertions(+) > > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c > index 13baf85b27d8..c5462513db90 100644 > --- a/kernel/trace/trace.c > +++ b/kernel/trace/trace.c > @@ -41,6 +41,7 @@ > #include > #include > #include > +#include > #include > > #include "trace.h" > @@ -8505,3 +8506,15 @@ __init static int clear_boot_tracer(void) > > fs_initcall(tracer_init_tracefs); > late_initcall_sync(clear_boot_tracer); > + > +#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK > +__init static int tracing_set_default_clock(void) > +{ > + /* sched_clock_stable() is determined in late_initcall */ > + if (!trace_boot_clock && !sched_clock_stable()) > + tracing_set_clock(&global_trace, "global"); > + > + return 0; > +} > +late_initcall_sync(tracing_set_default_clock); > +#endif ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] trace: Default to using trace_global_clock if sched_clock is unstable
Quoting Steven Rostedt (2018-03-30 14:48:45) > On Thu, 29 Mar 2018 23:25:57 +0100 > Chris Wilson wrote: > > > Across suspend, we may see a very large drift in timestamps if the sched > > clock is unstable, prompting the global trace's ringbuffer code to warn > > and suggest switching to the global clock. Preempt this request by > > detecting when the sched clock is unstable (determined during > > late_initcall) and automatically switching the default clock over to > > trace_global_clock. > > > > This should prevent requiring user interaction to resolve warnings such > > as: > > > > Delta way too big! 18446743856563626466 ts=18446744054496180323 write > > stamp = 197932553857 > > If you just came from a suspend/resume, > > please switch to the trace global clock: > > echo global > /sys/kernel/debug/tracing/trace_clock > > global clock has a much higher overhead than the local clock. I rather > not have it automatically switch even when there's no stable TSC. That > will be annoying to myself as I have boxes that this would switch on > and I prefer to keep the local clock. My counter argument would be that it comes as a bit of a shock to the user to find out their debugging session was rendered invalid because the tracer chose to use a clock that it knew was unsuitable for the job. :) > One can also decide the clock with the kernel command line. Should we > update that message to also say: > > Or set the global clock via the kernel command line with > "trace_clock=global" > > ? Sure, I was mainly floating the idea of trying to pick sensible defaults. Unstable clocks are quite rare nowadays, the ones we have in the lab are a pair of Core2 Duo. -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 00/24] drm_framebuffer boilerplate removal
Hi, I've been working on a getfb2[0] ioctl, which amongst other things supports multi-planar framebuffers as well as modifiers. getfb currently calls the framebuffer's handle_create hook, which doesn't support multiple planes. Thanks to Noralf's recent work, drivers can just store GEM objects directly in drm_framebuffer. I use this directly in getfb2: we need direct access to the GEM objects and not a vfunc in order to not hand out duplicate GEM names for the same object. This series converts all drivers except for nouveau, which was a little too non-trivial for my comfort, to storing GEM objects directly in drm_framebuffer. For those drivers whose driver_framebuffer struct was nothing but drm_framebuffer + BO, it deletes the driver-specific struct. It also makes use of Noralf's generic framebuffer helpers for create_handle and destroy where possible. I don't have the hardware for most of these drivers, so have had to settle for just staring really hard at the diff. I intend to remove create_handle when all drivers are converted over to placing BOs directly inside drm_framebuffer. For most drivers there's a relatively easy conversion to using the helpers for basically all framebuffer handling and fbdev emulation as well, though that's a bit further than I was willing to go without hardware to test on ... Cheers, Daniel [0]: https://lists.freedesktop.org/archives/dri-devel/2018-March/170512.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915: Do NOT skip the first 4k of stolen memory for pre-allocated buffers
Hi, On 30-03-18 15:25, Hans de Goede wrote: Hi, On 30-03-18 14:44, Chris Wilson wrote: Quoting Hans de Goede (2018-03-30 13:37:40) Hi, On 30-03-18 14:30, Chris Wilson wrote: Quoting Hans de Goede (2018-03-30 13:27:15) Before this commit the WaSkipStolenMemoryFirstPage workaround code was skipping the first 4k by passing 4096 as start of the address range passed to drm_mm_init(). This means that calling drm_mm_reserve_node() to try and reserve the firmware framebuffer so that we can inherit it would always fail, as the firmware framebuffer starts at address 0. Commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on everything >= gen8") says in its commit message: "This is confirmed to fix Skylake screen flickering issues (probably caused by the fact that we initialized a ring in the first page of stolen, but I didn't 100% confirm this theory)." Which suggests that it is safe to use the first page for a linear framebuffer as the firmware is doing. This commit always passes 0 as start to drm_mm_init() and works around WaSkipStolenMemoryFirstPage in i915_gem_stolen_insert_node_in_range() by insuring the start address passed by to drm_mm_insert_node_in_range() is always 4k or more. All entry points to i915_gem_stolen.c go through i915_gem_stolen_insert_node_in_range(), so that any newly allocated objects such as ring-buffers will not be allocated in the first 4k. The one exception is i915_gem_object_create_stolen_for_preallocated() which directly calls drm_mm_reserve_node() which now will be able to use the first 4k. This fixes the i915 driver no longer being able to inherit the firmware framebuffer on gen8+, which fixes the video output changing from the vendor logo to a black screen as soon as the i915 driver is loaded (on systems without fbcon). We've been told by the HW guys not to use the first page. (That's my understanding from every time this gets questioned.) Yet the GOP is happily using the first page. I think we may need to make a difference here between the GPU not using the first page and the display engine/pipeline not using the first page. Note that my patch only influences the inheriting of the initial framebuffer as allocated by the GOP. It does not influence any other allocations from the reserved range, those will still all avoid the first page. Without this patch fastboot / flickerfree support is essentially broken on any gen8+ hardware given that one of the goals of atomic is to be able to do flickerfree transitions I think that this warrants a closer look then just simply saying never use the first page. The concern is what else (i.e. nothing that we allocated ourselves) that may be in the first page... Given that the GOP has put its framebuffer there at least at boot there is nothing there, otherwise it would show up on the display. We have a whole bunch of code to inherit the BIOS fb in intel_display.c and AFAIK that code is there because this inheriting the BIOS fb is deemed an important feature. So I'm not happy at all with the handwavy best to not touch it answer I'm getting to this patch. Unless there are some clear answer from the hardware folks which specifically say we cannot put a framebuffer there (and then why is the GOP doing it?) then I believe that the best way forward here is to get various people to test with this patch and the best way to do that is probably to put it in next. Note I deliberately did not add a Cc stable. To elaborate on this, the excluding of the first 4k of the stolen memory region causes intel_alloc_initial_plane_obj() from intel_display.c to fail, which in turn causes intel_find_initial_plane_obj() to call intel_plane_disable_noatomic(intel_crtc, intel_plane); which temporarily completely turns off the display which leads to a very ugly flickering of the display at boot (as well as replacing the vendor logo with a black screen). I think we can all agree that this behavior is undesirable and even a regression in behavior caused by the fix to exclude the first 4k. Chris, if my patch is not an acceptable way to fix this, then how do you suggest that we fix this? Digging a bit deeper I found this: https://01.org/sites/default/files/documentation/intel-gfx-prm-osrc-kbl-vol16-workarounds.pdf Which says: "WaSkipStolenMemoryFirstPage: WA to skip the first page of stolen memory due to sporadic HW write on *CS Idle" And also about FBC: "First line of FBC getting corrupted when FBC compressed frame buffer offset is programmed to zero. Command streamers are doing flush writes to base of stolen. WA: New restriction to program FBC compressed frame buffer offset to at least 4KB." So using the first 4kB for the *framebuffer* as done by the GOP will not cause any major problems (freezes, hangs, etc.), and commit d43537610470 ("drm/i915: skip the first 4k of stolen memory on everything >= gen8") was correct in deducing that the problem was likely that some *vital* information was being stored i the first 4k and that go
[Intel-gfx] ✗ Fi.CI.IGT: failure for drm/i915/selftests: Avoid repeatedly harming the same innocent context
== Series Details == Series: drm/i915/selftests: Avoid repeatedly harming the same innocent context URL : https://patchwork.freedesktop.org/series/40941/ State : failure == Summary == Possible new issues: Test kms_cursor_legacy: Subgroup cursor-vs-flip-atomic-transitions: pass -> FAIL (shard-snb) Test kms_frontbuffer_tracking: Subgroup fbcpsr-2p-scndscrn-spr-indfb-move: skip -> FAIL (shard-snb) Subgroup fbcpsr-rgb101010-draw-render: skip -> FAIL (shard-snb) Subgroup psr-2p-primscrn-spr-indfb-onoff: skip -> FAIL (shard-snb) Test kms_plane_lowres: Subgroup pipe-a-tiling-none: pass -> FAIL (shard-snb) Test kms_vblank: Subgroup pipe-a-query-idle: pass -> FAIL (shard-snb) Known issues: Test gem_softpin: Subgroup noreloc-s3: pass -> INCOMPLETE (shard-snb) fdo#103375 Test kms_flip: Subgroup 2x-dpms-vs-vblank-race: fail -> PASS (shard-hsw) fdo#103060 Subgroup 2x-flip-vs-expired-vblank-interruptible: fail -> PASS (shard-hsw) fdo#102887 Subgroup flip-vs-blocking-wf-vblank: fail -> PASS (shard-hsw) fdo#100368 Test kms_setmode: Subgroup basic: fail -> PASS (shard-apl) fdo#99912 fdo#103375 https://bugs.freedesktop.org/show_bug.cgi?id=103375 fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060 fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887 fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368 fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912 shard-apltotal:3495 pass:1833 dwarn:1 dfail:0 fail:6 skip:1655 time:12857s shard-hswtotal:3495 pass:1783 dwarn:1 dfail:0 fail:1 skip:1709 time:11682s shard-snbtotal:3398 pass:1320 dwarn:1 dfail:0 fail:10 skip:2066 time:6563s Blacklisted hosts: shard-kbltotal:3495 pass:1958 dwarn:1 dfail:0 fail:8 skip:1528 time:9256s == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8548/shards.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] trace: Default to using trace_global_clock if sched_clock is unstable
On Fri, 30 Mar 2018 15:07:53 +0100 Chris Wilson wrote: > Sure, I was mainly floating the idea of trying to pick sensible > defaults. Unstable clocks are quite rare nowadays, the ones we have in > the lab are a pair of Core2 Duo. I still have a box too ;-) I'm not so against having global_clock become default if the TSC is unstable. But there needs to be a printk warning (not a WARN, but something like: Warning: TSC unstable, switching tracing_clock default to "global" If you want to keep local, then add "trace_clock=local" on the kernel command line. -- Steve ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 00/24] drm_framebuffer boilerplate removal
On Fri, Mar 30, 2018 at 10:11 AM, Daniel Stone wrote: > Hi, > I've been working on a getfb2[0] ioctl, which amongst other things > supports multi-planar framebuffers as well as modifiers. getfb > currently calls the framebuffer's handle_create hook, which doesn't > support multiple planes. > > Thanks to Noralf's recent work, drivers can just store GEM objects > directly in drm_framebuffer. I use this directly in getfb2: we need > direct access to the GEM objects and not a vfunc in order to not hand > out duplicate GEM names for the same object. > > This series converts all drivers except for nouveau, which was a > little too non-trivial for my comfort, to storing GEM objects directly > in drm_framebuffer. For those drivers whose driver_framebuffer struct > was nothing but drm_framebuffer + BO, it deletes the driver-specific > struct. It also makes use of Noralf's generic framebuffer helpers for > create_handle and destroy where possible. > > I don't have the hardware for most of these drivers, so have had to > settle for just staring really hard at the diff. > > I intend to remove create_handle when all drivers are converted over > to placing BOs directly inside drm_framebuffer. For most drivers > there's a relatively easy conversion to using the helpers for > basically all framebuffer handling and fbdev emulation as well, though > that's a bit further than I was willing to go without hardware to test > on ... Series is: Acked-by: Alex Deucher > > Cheers, > Daniel > > [0]: https://lists.freedesktop.org/archives/dri-devel/2018-March/170512.html > ___ > amd-gfx mailing list > amd-...@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH] drm/i915/execlists: Consistent seqno reporting in GEM_TRACE
Hi Tvrtko, Thank you for the patch! Yet something to improve: [auto build test ERROR on drm-intel/for-linux-next] [also build test ERROR on next-20180329] [cannot apply to v4.16-rc7] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Tvrtko-Ursulin/drm-i915-execlists-Consistent-seqno-reporting-in-GEM_TRACE/20180330-120802 base: git://anongit.freedesktop.org/drm-intel for-linux-next config: i386-randconfig-x0-03302126 (attached as .config) compiler: gcc-5 (Debian 5.5.0-3) 5.4.1 20171010 reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): In file included from include/linux/interrupt.h:6:0, from drivers/gpu//drm/i915/intel_lrc.c:134: drivers/gpu//drm/i915/intel_lrc.c: In function 'execlists_cancel_port_requests': >> drivers/gpu//drm/i915/intel_lrc.c:730:13: error: format '%lu' expects >> argument of type 'long unsigned int', but argument 3 has type 'int' >> [-Werror=format=] GEM_TRACE("%s:port%lu cancel %llx:%d [global %d]\n", ^ include/linux/kernel.h:635:33: note: in definition of macro '__trace_printk_check_format' trace_printk_check_format(fmt, ##args); \ ^ include/linux/kernel.h:672:3: note: in expansion of macro 'do_trace_printk' do_trace_printk(fmt, ##__VA_ARGS__); \ ^ drivers/gpu//drm/i915/i915_gem.h:55:24: note: in expansion of macro 'trace_printk' #define GEM_TRACE(...) trace_printk(__VA_ARGS__) ^ drivers/gpu//drm/i915/intel_lrc.c:730:3: note: in expansion of macro 'GEM_TRACE' GEM_TRACE("%s:port%lu cancel %llx:%d [global %d]\n", ^ drivers/gpu//drm/i915/intel_lrc.c:730:13: error: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'int' [-Werror=format=] GEM_TRACE("%s:port%lu cancel %llx:%d [global %d]\n", ^ include/linux/kernel.h:688:29: note: in definition of macro 'do_trace_printk' __trace_printk(_THIS_IP_, fmt, ##args); \ ^ drivers/gpu//drm/i915/i915_gem.h:55:24: note: in expansion of macro 'trace_printk' #define GEM_TRACE(...) trace_printk(__VA_ARGS__) ^ drivers/gpu//drm/i915/intel_lrc.c:730:3: note: in expansion of macro 'GEM_TRACE' GEM_TRACE("%s:port%lu cancel %llx:%d [global %d]\n", ^ cc1: all warnings being treated as errors vim +730 drivers/gpu//drm/i915/intel_lrc.c 720 721 void 722 execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) 723 { 724 struct execlist_port *port = execlists->port; 725 unsigned int num_ports = execlists_num_ports(execlists); 726 727 while (num_ports-- && port_isset(port)) { 728 struct i915_request *rq = port_request(port); 729 > 730 GEM_TRACE("%s:port%lu cancel %llx:%d [global %d]\n", 731rq->engine->name, port - execlists->port, 732rq->fence.context, rq->fence.seqno, rq->global_seqno); 733 734 GEM_BUG_ON(!execlists->active); 735 intel_engine_context_out(rq->engine); 736 737 execlists_context_status_change(rq, 738 i915_request_completed(rq) ? 739 INTEL_CONTEXT_SCHEDULE_OUT : 740 INTEL_CONTEXT_SCHEDULE_PREEMPTED); 741 742 i915_request_put(rq); 743 744 memset(port, 0, sizeof(*port)); 745 port++; 746 } 747 } 748 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 1/2] trace: Default to using trace_global_clock if sched_clock is unstable
Across suspend, we may see a very large drift in timestamps if the sched clock is unstable, prompting the global trace's ringbuffer code to warn and suggest switching to the global clock. Preempt this request by detecting when the sched clock is unstable (determined during late_initcall) and automatically switching the default clock over to trace_global_clock. This should prevent requiring user interaction to resolve warnings such as: Delta way too big! 18446743856563626466 ts=18446744054496180323 write stamp = 197932553857 If you just came from a suspend/resume, please switch to the trace global clock: echo global > /sys/kernel/debug/tracing/trace_clock Signed-off-by: Chris Wilson Cc: Steven Rostedt (VMware) --- v2: Tell the user what's happening and what they can do to correct it. --- kernel/trace/trace.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 13baf85b27d8..7c155fa879e1 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include "trace.h" @@ -8505,3 +8506,21 @@ __init static int clear_boot_tracer(void) fs_initcall(tracer_init_tracefs); late_initcall_sync(clear_boot_tracer); + +#ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK +__init static int tracing_set_default_clock(void) +{ + /* sched_clock_stable() is determined in late_initcall */ + if (trace_boot_clock || sched_clock_stable()) { + printk(KERN_WARNING + "Unstable clock detected, switching default tracing clock to \"global\"\n" + "If you want to keep using the local clock, then add:\n" + " \"trace_clock=local\"\n" + "on the kernel command line\n"); + tracing_set_clock(&global_trace, "global"); + } + + return 0; +} +late_initcall_sync(tracing_set_default_clock); +#endif -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v2 2/2] trace: Mention trace_clock=global when warning about unstable clocks
Mention the alternative of adding trace_clock=global to the kernel command line when we detect that we've used an unstable clock across a suspend/resume cycle. Signed-off-by: Chris Wilson Cc: Steven Rostedt --- kernel/trace/ring_buffer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index dcf1c4dd3efe..88098d7fac06 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -2637,7 +2637,8 @@ rb_handle_timestamp(struct ring_buffer_per_cpu *cpu_buffer, sched_clock_stable() ? "" : "If you just came from a suspend/resume,\n" "please switch to the trace global clock:\n" - " echo global > /sys/kernel/debug/tracing/trace_clock\n"); + " echo global > /sys/kernel/debug/tracing/trace_clock\n" + "or add trace_clock=global to the kernel command line\n"); info->add_timestamp = 1; } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v2,1/2] trace: Default to using trace_global_clock if sched_clock is unstable
== Series Details == Series: series starting with [v2,1/2] trace: Default to using trace_global_clock if sched_clock is unstable URL : https://patchwork.freedesktop.org/series/40952/ State : warning == Summary == $ dim checkpatch origin/drm-tip 935d891f5719 trace: Default to using trace_global_clock if sched_clock is unstable -:17: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line) #17: Delta way too big! 18446743856563626466 ts=18446744054496180323 write stamp = 197932553857 -:47: WARNING:PREFER_PR_LEVEL: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... #47: FILE: kernel/trace/trace.c:8515: + printk(KERN_WARNING total: 0 errors, 2 warnings, 0 checks, 28 lines checked 660298fe1189 trace: Mention trace_clock=global when warning about unstable clocks ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v12 01/17] drm/i915/guc/slpc: Add SLPC control to enable_guc modparam
Thanks for the review. Will update with all suggestions in the next rev. On 3/30/2018 6:07 PM, Michal Wajdeczko wrote: On Fri, 30 Mar 2018 10:31:46 +0200, Sagar Arun Kamble wrote: From: Tom O'Rourke GuC is currently being used for submission and HuC authentication. Choices can be configured through enable_guc modparam. GuC SLPC is GT Power and Performance management feature in GuC. Add another option to enable_guc modparam to control SLPC. v1: Add early call to sanitize enable_guc_slpc in intel_guc_ucode_init Remove sanitize enable_guc_slpc call before firmware version check is performed. (ChrisW) Version check is added in next patch and that will be done as part of slpc_enable_sanitize function in the next patch. (Sagar) Updated slpc option sanitize function call for platforms without GuC support. This was caught by CI BAT. v2: Changed parameter to dev_priv for HAS_SLPC macro. (David) Code indentation based on checkpatch. v3: Rebase. v4: Moved sanitization of SLPC option post GuC load. v5: Removed function intel_slpc_enabled. Planning to rely only on kernel parameter. Moved sanitization prior to GuC load to use the parameter during SLPC state setup during to GuC load. (Sagar) v6: Commit message update. Rebase. v7: Moved SLPC option sanitization to intel_uc_sanitize_options. v8: Clearing SLPC option on GuC load failure. Change moved from later patch. (Sagar) v9: s/enable_slpc/enable_guc_slpc. Rebase w.r.t modparam change. v10: Rebase. Separate modparam is not needed now that we maintain all options in single param enable_guc. Suggested-by: Paulo Zanoni Signed-off-by: Tom O'Rourke Signed-off-by: Sagar Arun Kamble Cc: Chris Wilson Cc: Joonas Lahtinen Cc: Radoslaw Szwichtenberg Cc: Michal Wajdeczko Cc: Sujaritha Sundaresan Cc: Jeff McGee --- drivers/gpu/drm/i915/i915_params.c | 5 +++-- drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/intel_uc.c | 23 +++ drivers/gpu/drm/i915/intel_uc.h | 6 ++ 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 08108ce..40b799b 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -150,9 +150,10 @@ i915_param_named_unsafe(edp_vswing, int, 0400, "2=default swing(400mV))"); i915_param_named_unsafe(enable_guc, int, 0400, - "Enable GuC load for GuC submission and/or HuC load. " + "Enable GuC load for GuC submission and/or HuC load and/or GuC SLPC. " "Required functionality can be selected using bitmask values. " - "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load)"); + "(-1=auto, 0=disable [default], 1=GuC submission, 2=HuC load, " + "4=GuC SLPC)"); Maybe to avoid later surprise, we should explicitly say that: + "4=GuC SLPC [requires GuC submission])"); i915_param_named(guc_log_level, int, 0400, "GuC firmware logging level. Requires GuC to be loaded. " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index c963603..2484925 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -32,6 +32,7 @@ struct drm_printer; #define ENABLE_GUC_SUBMISSION BIT(0) #define ENABLE_GUC_LOAD_HUC BIT(1) +#define ENABLE_GUC_SLPC BIT(2) #define I915_PARAMS_FOR_EACH(param) \ param(char *, vbt_firmware, NULL) \ diff --git a/drivers/gpu/drm/i915/intel_uc.c b/drivers/gpu/drm/i915/intel_uc.c index 1cffaf7..0e4a97f 100644 --- a/drivers/gpu/drm/i915/intel_uc.c +++ b/drivers/gpu/drm/i915/intel_uc.c @@ -56,9 +56,15 @@ static int __get_platform_enable_guc(struct drm_i915_private *dev_priv) struct intel_uc_fw *huc_fw = &dev_priv->huc.fw; int enable_guc = 0; - /* Default is to enable GuC/HuC if we know their firmwares */ - if (intel_uc_fw_is_selected(guc_fw)) + /* + * Default is to enable GuC submission/SLPC/HuC if we know their + * firmwares + */ + if (intel_uc_fw_is_selected(guc_fw)) { enable_guc |= ENABLE_GUC_SUBMISSION; + enable_guc |= ENABLE_GUC_SLPC; + } + if (intel_uc_fw_is_selected(huc_fw)) enable_guc |= ENABLE_GUC_LOAD_HUC; @@ -110,10 +116,11 @@ static void sanitize_options_early(struct drm_i915_private *dev_priv) if (i915_modparams.enable_guc < 0) i915_modparams.enable_guc = __get_platform_enable_guc(dev_priv); - DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s)\n", + DRM_DEBUG_DRIVER("enable_guc=%d (submission:%s huc:%s slpc:%s)\n", i915_modparams.enable_guc, yesno(intel_uc_is_using_guc_submission()), - yesno(intel_uc_is_using_huc())); + yesno(intel_uc_is_using_huc()), + yesno(intel_uc_is_using_guc_slpc())); /* Verify GuC firmware availability */ if (intel_uc_is_using_guc() && !intel_uc_fw_is_selected(guc_fw)) { @@ -123,6 +130,14
[Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [v2,1/2] trace: Default to using trace_global_clock if sched_clock is unstable
== Series Details == Series: series starting with [v2,1/2] trace: Default to using trace_global_clock if sched_clock is unstable URL : https://patchwork.freedesktop.org/series/40952/ State : failure == Summary == Series 40952v1 series starting with [v2,1/2] trace: Default to using trace_global_clock if sched_clock is unstable https://patchwork.freedesktop.org/api/1.0/series/40952/revisions/1/mbox/ Possible new issues: Test kms_pipe_crc_basic: Subgroup nonblocking-crc-pipe-c-frame-sequence: pass -> FAIL (fi-skl-guc) Known issues: Test kms_pipe_crc_basic: Subgroup suspend-read-crc-pipe-b: pass -> INCOMPLETE (fi-snb-2520m) fdo#103713 fdo#103713 https://bugs.freedesktop.org/show_bug.cgi?id=103713 fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:438s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:444s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:381s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:533s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:297s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:516s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:513s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:520s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:508s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:410s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:560s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:515s fi-cnl-y3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:579s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:423s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:314s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:542s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:405s fi-ilk-650 total:285 pass:225 dwarn:0 dfail:0 fail:0 skip:60 time:420s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:470s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:428s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:469s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:462s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:513s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:660s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:450s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:533s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:508s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:495s fi-skl-guc total:285 pass:256 dwarn:0 dfail:0 fail:1 skip:28 time:427s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:446s fi-snb-2520m total:242 pass:208 dwarn:0 dfail:0 fail:0 skip:33 fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:400s Blacklisted hosts: fi-cnl-psr total:285 pass:256 dwarn:3 dfail:0 fail:0 skip:26 time:513s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:487s 335ef9849310af26d65c54f7d2d2e9dcbce238b9 drm-tip: 2018y-03m-30d-09h-08m-40s UTC integration manifest 660298fe1189 trace: Mention trace_clock=global when warning about unstable clocks 935d891f5719 trace: Default to using trace_global_clock if sched_clock is unstable == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8549/issues.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH v1] drm/i915/gen11: Preempt-to-idle support in execlists.
On 2018-03-29 00:28, Chris Wilson wrote: Quoting Lis, Tomasz (2018-03-28 17:06:58) On 2018-03-28 01:27, Chris Wilson wrote: Quoting Tomasz Lis (2018-03-27 16:17:59) The patch adds support of preempt-to-idle requesting by setting a proper bit within Execlist Control Register, and receiving preemption result from Context Status Buffer. Preemption in previous gens required a special batch buffer to be executed, so the Command Streamer never preempted to idle directly. In Icelake it is possible, as there is a hardware mechanism to inform the kernel about status of the preemption request. This patch does not cover using the new preemption mechanism when GuC is active. Bspec: 18922 Signed-off-by: Tomasz Lis --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_pci.c | 3 ++- drivers/gpu/drm/i915/intel_device_info.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 45 +++- drivers/gpu/drm/i915/intel_lrc.h | 1 + 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 800230b..c32580b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2514,6 +2514,8 @@ intel_info(const struct drm_i915_private *dev_priv) ((dev_priv)->info.has_logical_ring_elsq) #define HAS_LOGICAL_RING_PREEMPTION(dev_priv) \ ((dev_priv)->info.has_logical_ring_preemption) +#define HAS_HW_PREEMPT_TO_IDLE(dev_priv) \ + ((dev_priv)->info.has_hw_preempt_to_idle) #define HAS_EXECLISTS(dev_priv) HAS_LOGICAL_RING_CONTEXTS(dev_priv) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index 4364922..66b6700 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -595,7 +595,8 @@ static const struct intel_device_info intel_cannonlake_info = { GEN(11), \ .ddb_size = 2048, \ .has_csr = 0, \ - .has_logical_ring_elsq = 1 + .has_logical_ring_elsq = 1, \ + .has_hw_preempt_to_idle = 1 static const struct intel_device_info intel_icelake_11_info = { GEN11_FEATURES, diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index 933e316..4eb97b5 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -98,6 +98,7 @@ enum intel_platform { func(has_logical_ring_contexts); \ func(has_logical_ring_elsq); \ func(has_logical_ring_preemption); \ + func(has_hw_preempt_to_idle); \ func(has_overlay); \ func(has_pooled_eu); \ func(has_psr); \ diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index ba7f783..1a22de4 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -153,6 +153,7 @@ #define GEN8_CTX_STATUS_ACTIVE_IDLE(1 << 3) #define GEN8_CTX_STATUS_COMPLETE (1 << 4) #define GEN8_CTX_STATUS_LITE_RESTORE (1 << 15) +#define GEN11_CTX_STATUS_PREEMPT_IDLE (1 << 29) #define GEN8_CTX_STATUS_COMPLETED_MASK \ (GEN8_CTX_STATUS_COMPLETE | GEN8_CTX_STATUS_PREEMPTED) @@ -183,7 +184,9 @@ static inline bool need_preempt(const struct intel_engine_cs *engine, const struct i915_request *last, int prio) { - return engine->i915->preempt_context && prio > max(rq_prio(last), 0); + return (engine->i915->preempt_context || + HAS_HW_PREEMPT_TO_IDLE(engine->i915)) && Well, you haven't actually disabled allocating the preempt_context so... Yes.. I had mixed feelings about changing needs_preempt_context() now, as that would mean adding a temporary condition on GuC until the GuC preemption is merged. I will add the conditions and disable the allocation in v2 of the patch. But at any rate, making this an engine->flag would eliminate one pointer dance. Could be an interesting idea for a separate patch. To land first ;) :) Sure, I can do that. +prio > max(rq_prio(last), 0); } /** @@ -535,6 +538,25 @@ static void inject_preempt_context(struct intel_engine_cs *engine) execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT); } +static void gen11_preempt_to_idle(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists *execlists = &engine->execlists; + + GEM_TRACE("%s\n", engine->name); + + /* +* hardware which HAS_HW_PREEMPT_TO_IDLE(), always also +* HAS_LOGICAL_RING_ELSQ(), so we can assume ctrl_reg is set +*/ + GEM_BUG_ON(execlists->ctrl_reg != NULL); + + /* trigger preemption to idle */ + writel(EL_CTRL_PREEMPT_TO_IDLE, execlists->ctrl_reg); Future plans? Because just inserting the branch into the setter of inject_preempt_contex
[Intel-gfx] Preemption reset from timer; CI now 110% happier
Fixed up the couple of bugs in the selftests that CI was tripping over, or so I hope... -Chris ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context
We don't handle resetting the kernel context very well, or presumably any context executing its breadcrumb commands in the ring as opposed to the batchbuffer and flush. If we trigger a device reset twice in quick succession while the kernel context is executing, we may end up skipping the breadcrumb. This is really only a problem for the selftest as normally there is a large interlude between resets (hangcheck), or we focus on resetting just one engine and so avoid repeatedly resetting innocents. Something to try would be a preempt-to-idle to quiesce the engine before reset, so that innocent contexts would be spared the reset. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry --- drivers/gpu/drm/i915/i915_drv.c | 3 ++ drivers/gpu/drm/i915/selftests/intel_hangcheck.c | 48 ++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index d354627882e3..684060ed8db6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1886,6 +1886,8 @@ void i915_reset(struct drm_i915_private *i915) int ret; int i; + GEM_TRACE("flags=%lx\n", error->flags); + might_sleep(); lockdep_assert_held(&i915->drm.struct_mutex); GEM_BUG_ON(!test_bit(I915_RESET_BACKOFF, &error->flags)); @@ -2016,6 +2018,7 @@ int i915_reset_engine(struct intel_engine_cs *engine, const char *msg) struct i915_request *active_request; int ret; + GEM_TRACE("%s flags=%lx\n", engine->name, error->flags); GEM_BUG_ON(!test_bit(I915_RESET_ENGINE + engine->id, &error->flags)); active_request = i915_gem_reset_prepare_engine(engine); diff --git a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c index 9e4e0ad62724..d03abe7f8a53 100644 --- a/drivers/gpu/drm/i915/selftests/intel_hangcheck.c +++ b/drivers/gpu/drm/i915/selftests/intel_hangcheck.c @@ -979,6 +979,23 @@ static int igt_wait_reset(void *arg) return err; } +static int wait_for_others(struct drm_i915_private *i915, + struct intel_engine_cs *exclude) +{ + struct intel_engine_cs *engine; + enum intel_engine_id id; + + for_each_engine(engine, i915, id) { + if (engine == exclude) + continue; + + if (wait_for(intel_engine_is_idle(engine), 10)) + return -EIO; + } + + return 0; +} + static int igt_reset_queue(void *arg) { struct drm_i915_private *i915 = arg; @@ -1027,13 +1044,36 @@ static int igt_reset_queue(void *arg) i915_request_get(rq); __i915_request_add(rq, true); + /* +* XXX We don't handle resetting the kernel context +* very well. If we trigger a device reset twice in +* quick succession while the kernel context is +* executing, we may end up skipping the breadcrumb. +* This is really only a problem for the selftest as +* normally there is a large interlude between resets +* (hangcheck), or we focus on resetting just one +* engine and so avoid repeatedly resetting innocents. +*/ + err = wait_for_others(i915, engine); + if (err) { + pr_err("%s(%s): Failed to idle other inactive engines after device reset\n", + __func__, engine->name); + i915_request_put(rq); + i915_request_put(prev); + + GEM_TRACE_DUMP(); + i915_gem_set_wedged(i915); + goto fini; + } + if (!wait_for_hang(&h, prev)) { struct drm_printer p = drm_info_printer(i915->drm.dev); - pr_err("%s: Failed to start request %x, at %x\n", - __func__, prev->fence.seqno, hws_seqno(&h, prev)); - intel_engine_dump(prev->engine, &p, - "%s\n", prev->engine->name); + pr_err("%s(%s): Failed to start request %x, at %x\n", + __func__, engine->name, + prev->fence.seqno, hws_seqno(&h, prev)); + intel_engine_dump(engine, &p, + "%s\n", engine->name); i915_request_put(rq); i915_request_put(prev)
[Intel-gfx] [PATCH 04/18] drm/i915/execlists: Refactor out complete_preempt_context()
As a complement to inject_preempt_context(), follow up with the function to handle its completion. This will be useful should we wish to extend the duties of the preempt-context for execlists. v2: And do the same for the guc. Signed-off-by: Chris Wilson Cc: Jeff McGee Cc: Michał Winiarski Reviewed-by: Jeff McGee #v1 --- drivers/gpu/drm/i915/intel_guc_submission.c | 26 +- drivers/gpu/drm/i915/intel_lrc.c| 23 +-- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 207cda062626..ef2e29959c5b 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -621,6 +621,21 @@ static void wait_for_guc_preempt_report(struct intel_engine_cs *engine) report->report_return_status = INTEL_GUC_REPORT_STATUS_UNKNOWN; } +static void complete_preempt_context(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists *execlists = &engine->execlists; + + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + + execlists_cancel_port_requests(execlists); + execlists_unwind_incomplete_requests(execlists); + + wait_for_guc_preempt_report(engine); + intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0); + + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); +} + /** * guc_submit() - Submit commands through GuC * @engine: engine associated with the commands @@ -762,15 +777,8 @@ static void guc_submission_tasklet(unsigned long data) if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT) && intel_read_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX) == - GUC_PREEMPT_FINISHED) { - execlists_cancel_port_requests(&engine->execlists); - execlists_unwind_incomplete_requests(execlists); - - wait_for_guc_preempt_report(engine); - - execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); - intel_write_status_page(engine, I915_GEM_HWS_PREEMPT_INDEX, 0); - } + GUC_PREEMPT_FINISHED) + complete_preempt_context(engine); if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)) guc_dequeue(engine); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a3fd9683f9d1..51e930323626 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -545,8 +545,18 @@ static void inject_preempt_context(struct intel_engine_cs *engine) if (execlists->ctrl_reg) writel(EL_CTRL_LOAD, execlists->ctrl_reg); - execlists_clear_active(&engine->execlists, EXECLISTS_ACTIVE_HWACK); - execlists_set_active(&engine->execlists, EXECLISTS_ACTIVE_PREEMPT); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_HWACK); + execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); +} + +static void complete_preempt_context(struct intel_engine_execlists *execlists) +{ + GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + + execlists_cancel_port_requests(execlists); + execlists_unwind_incomplete_requests(execlists); + + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } static void execlists_dequeue(struct intel_engine_cs *engine) @@ -994,14 +1004,7 @@ static void execlists_submission_tasklet(unsigned long data) if (status & GEN8_CTX_STATUS_COMPLETE && buf[2*head + 1] == execlists->preempt_complete_status) { GEM_TRACE("%s preempt-idle\n", engine->name); - - execlists_cancel_port_requests(execlists); - execlists_unwind_incomplete_requests(execlists); - - GEM_BUG_ON(!execlists_is_active(execlists, - EXECLISTS_ACTIVE_PREEMPT)); - execlists_clear_active(execlists, - EXECLISTS_ACTIVE_PREEMPT); + complete_preempt_context(execlists); continue; } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 05/18] drm/i915: Move engine reset prepare/finish to backends
In preparation to more carefully handling incomplete preemption during reset by execlists, we move the existing code wholesale to the backends under a couple of new reset vfuncs. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Reviewed-by: Jeff McGee --- drivers/gpu/drm/i915/i915_gem.c | 47 +++--- drivers/gpu/drm/i915/intel_lrc.c| 59 +++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 23 +++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 9 +++-- 4 files changed, 88 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9650a7b10c5f..038867c96809 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2917,7 +2917,7 @@ static bool engine_stalled(struct intel_engine_cs *engine) struct i915_request * i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) { - struct i915_request *request = NULL; + struct i915_request *request; /* * During the reset sequence, we must prevent the engine from @@ -2940,40 +2940,7 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ kthread_park(engine->breadcrumbs.signaler); - /* -* Prevent request submission to the hardware until we have -* completed the reset in i915_gem_reset_finish(). If a request -* is completed by one engine, it may then queue a request -* to a second via its execlists->tasklet *just* as we are -* calling engine->init_hw() and also writing the ELSP. -* Turning off the execlists->tasklet until the reset is over -* prevents the race. -* -* Note that this needs to be a single atomic operation on the -* tasklet (flush existing tasks, prevent new tasks) to prevent -* a race between reset and set-wedged. It is not, so we do the best -* we can atm and make sure we don't lock the machine up in the more -* common case of recursively being called from set-wedged from inside -* i915_reset. -*/ - if (!atomic_read(&engine->execlists.tasklet.count)) - tasklet_kill(&engine->execlists.tasklet); - tasklet_disable(&engine->execlists.tasklet); - - /* -* We're using worker to queue preemption requests from the tasklet in -* GuC submission mode. -* Even though tasklet was disabled, we may still have a worker queued. -* Let's make sure that all workers scheduled before disabling the -* tasklet are completed before continuing with the reset. -*/ - if (engine->i915->guc.preempt_wq) - flush_workqueue(engine->i915->guc.preempt_wq); - - if (engine->irq_seqno_barrier) - engine->irq_seqno_barrier(engine); - - request = i915_gem_find_active_request(engine); + request = engine->reset.prepare(engine); if (request && request->fence.error == -EIO) request = ERR_PTR(-EIO); /* Previous reset failed! */ @@ -3114,13 +3081,8 @@ void i915_gem_reset_engine(struct intel_engine_cs *engine, if (request) request = i915_gem_reset_request(engine, request); - if (request) { - DRM_DEBUG_DRIVER("resetting %s to restart from tail of request 0x%x\n", -engine->name, request->global_seqno); - } - /* Setup the CS to resume from the breadcrumb of the hung request */ - engine->reset_hw(engine, request); + engine->reset.reset(engine, request); } void i915_gem_reset(struct drm_i915_private *dev_priv) @@ -3172,7 +3134,8 @@ void i915_gem_reset(struct drm_i915_private *dev_priv) void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { - tasklet_enable(&engine->execlists.tasklet); + engine->reset.finish(engine); + kthread_unpark(engine->breadcrumbs.signaler); intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 51e930323626..42f9af625e88 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1732,8 +1732,48 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) return init_workarounds_ring(engine); } -static void reset_common_ring(struct intel_engine_cs *engine, - struct i915_request *request) +static struct i915_request * +execlists_reset_prepare(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + GEM_TRACE("%s\n", engine->name); + + /* +* Prevent request submission to the hardware until we have +* completed the reset in i915_gem_reset_finish(). If a request +* is completed by one engine, it may then queue a request +* to a second
[Intel-gfx] [PATCH 10/18] drm/i915: Combine tasklet_kill and tasklet_disable
Ideally, we want to atomically flush and disable the tasklet before resetting the GPU. At present, we rely on being the only part to touch our tasklet and serialisation of the reset process to ensure that we can suspend the tasklet from the mix of reset/wedge pathways. In this patch, we move the tasklet abuse into its own function and tweak it such that we only do a synchronous operation the first time it is disabled around the reset. This allows us to avoid the sync inside a softirq context in subsequent patches. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cba1ecda126a..8fe9e62c5d18 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1745,6 +1745,16 @@ static int gen9_init_render_ring(struct intel_engine_cs *engine) return init_workarounds_ring(engine); } +static void tasklet_kill_and_disable(struct tasklet_struct *t) +{ + if (!atomic_read(&t->count)) + tasklet_kill(t); + + if (atomic_inc_return(&t->count) == 1) + tasklet_unlock_wait(t); + smp_mb(); +} + static struct i915_request * execlists_reset_prepare(struct intel_engine_cs *engine) { @@ -1769,9 +1779,7 @@ execlists_reset_prepare(struct intel_engine_cs *engine) * common case of recursively being called from set-wedged from inside * i915_reset. */ - if (!atomic_read(&execlists->tasklet.count)) - tasklet_kill(&execlists->tasklet); - tasklet_disable(&execlists->tasklet); + tasklet_kill_and_disable(&execlists->tasklet); /* * We want to flush the pending context switches, having disabled -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 11/18] drm/i915: Stop parking the signaler around reset
We cannot call kthread_park() from softirq context, so let's avoid it entirely during the reset. We wanted to suspend the signaler so that it would not mark a request as complete at the same time as we marked it as being in error. Instead of parking the signaling, stop the engine from advancing so that the GPU doesn't emit the breadcrumb for our chosen "guilty" request. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/i915_gem.c | 14 -- drivers/gpu/drm/i915/intel_lrc.c| 21 + drivers/gpu/drm/i915/intel_ringbuffer.c | 18 ++ 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 038867c96809..8a6acb1d5ad3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2928,18 +2928,6 @@ i915_gem_reset_prepare_engine(struct intel_engine_cs *engine) */ intel_uncore_forcewake_get(engine->i915, FORCEWAKE_ALL); - /* -* Prevent the signaler thread from updating the request -* state (by calling dma_fence_signal) as we are processing -* the reset. The write from the GPU of the seqno is -* asynchronous and the signaler thread may see a different -* value to us and declare the request complete, even though -* the reset routine have picked that request as the active -* (incomplete) request. This conflict is not handled -* gracefully! -*/ - kthread_park(engine->breadcrumbs.signaler); - request = engine->reset.prepare(engine); if (request && request->fence.error == -EIO) request = ERR_PTR(-EIO); /* Previous reset failed! */ @@ -3136,8 +3124,6 @@ void i915_gem_reset_finish_engine(struct intel_engine_cs *engine) { engine->reset.finish(engine); - kthread_unpark(engine->breadcrumbs.signaler); - intel_uncore_forcewake_put(engine->i915, FORCEWAKE_ALL); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8fe9e62c5d18..731f8de56ea0 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1755,6 +1755,21 @@ static void tasklet_kill_and_disable(struct tasklet_struct *t) smp_mb(); } +static void set_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + GEM_TRACE("%s\n", engine->name); + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (__intel_wait_for_register_fw(dev_priv, +mode, MODE_IDLE, MODE_IDLE, +1000, 0, +NULL)) + GEM_TRACE("%s: timed out on STOP_RING -> IDLE\n", engine->name); +} + static struct i915_request * execlists_reset_prepare(struct intel_engine_cs *engine) { @@ -1801,6 +1816,12 @@ execlists_reset_prepare(struct intel_engine_cs *engine) if (request) { unsigned long flags; + /* +* Prevent the breadcrumb from advancing before we decide +* which request is currently active. +*/ + set_stop_engine(engine); + spin_lock_irqsave(&engine->timeline->lock, flags); list_for_each_entry_from_reverse(request, &engine->timeline->requests, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 5dadbc435c0e..226c00aecd8a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -530,8 +530,26 @@ static int init_ring_common(struct intel_engine_cs *engine) return ret; } +static void set_stop_engine(struct intel_engine_cs *engine) +{ + struct drm_i915_private *dev_priv = engine->i915; + const u32 base = engine->mmio_base; + const i915_reg_t mode = RING_MI_MODE(base); + + I915_WRITE_FW(mode, _MASKED_BIT_ENABLE(STOP_RING)); + if (__intel_wait_for_register_fw(dev_priv, +mode, MODE_IDLE, MODE_IDLE, +1000, 0, +NULL)) + DRM_DEBUG_DRIVER("%s: timed out on STOP_RING\n", +engine->name); +} + static struct i915_request *reset_prepare(struct intel_engine_cs *engine) { + if (INTEL_GEN(engine->i915) >= 3) + set_stop_engine(engine); + if (engine->irq_seqno_barrier) engine->irq_seqno_barrier(engine); -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org
[Intel-gfx] [PATCH 06/18] drm/i915: Split execlists/guc reset prepartions
In the next patch, we will make the execlists reset prepare callback take into account preemption by flushing the context-switch handler. This is not applicable to the GuC submission backend, so split the two into their own backend callbacks. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Reviewed-by: Jeff McGee --- drivers/gpu/drm/i915/intel_guc_submission.c | 41 + drivers/gpu/drm/i915/intel_lrc.c| 11 +--- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index ef2e29959c5b..0e0655430480 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -784,6 +784,46 @@ static void guc_submission_tasklet(unsigned long data) guc_dequeue(engine); } +static struct i915_request * +guc_reset_prepare(struct intel_engine_cs *engine) +{ + struct intel_engine_execlists * const execlists = &engine->execlists; + + GEM_TRACE("%s\n", engine->name); + + /* +* Prevent request submission to the hardware until we have +* completed the reset in i915_gem_reset_finish(). If a request +* is completed by one engine, it may then queue a request +* to a second via its execlists->tasklet *just* as we are +* calling engine->init_hw() and also writing the ELSP. +* Turning off the execlists->tasklet until the reset is over +* prevents the race. +* +* Note that this needs to be a single atomic operation on the +* tasklet (flush existing tasks, prevent new tasks) to prevent +* a race between reset and set-wedged. It is not, so we do the best +* we can atm and make sure we don't lock the machine up in the more +* common case of recursively being called from set-wedged from inside +* i915_reset. +*/ + if (!atomic_read(&execlists->tasklet.count)) + tasklet_kill(&execlists->tasklet); + tasklet_disable(&execlists->tasklet); + + /* +* We're using worker to queue preemption requests from the tasklet in +* GuC submission mode. +* Even though tasklet was disabled, we may still have a worker queued. +* Let's make sure that all workers scheduled before disabling the +* tasklet are completed before continuing with the reset. +*/ + if (engine->i915->guc.preempt_wq) + flush_workqueue(engine->i915->guc.preempt_wq); + + return i915_gem_find_active_request(engine); +} + /* * Everything below here is concerned with setup & teardown, and is * therefore not part of the somewhat time-critical batch-submission @@ -1243,6 +1283,7 @@ int intel_guc_submission_enable(struct intel_guc *guc) &engine->execlists; execlists->tasklet.func = guc_submission_tasklet; + engine->reset.prepare = guc_reset_prepare; engine->park = guc_submission_park; engine->unpark = guc_submission_unpark; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 42f9af625e88..5c1324c37549 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1759,16 +1759,6 @@ execlists_reset_prepare(struct intel_engine_cs *engine) tasklet_kill(&execlists->tasklet); tasklet_disable(&execlists->tasklet); - /* -* We're using worker to queue preemption requests from the tasklet in -* GuC submission mode. -* Even though tasklet was disabled, we may still have a worker queued. -* Let's make sure that all workers scheduled before disabling the -* tasklet are completed before continuing with the reset. -*/ - if (engine->i915->guc.preempt_wq) - flush_workqueue(engine->i915->guc.preempt_wq); - return i915_gem_find_active_request(engine); } @@ -2158,6 +2148,7 @@ static void execlists_set_default_submission(struct intel_engine_cs *engine) engine->cancel_requests = execlists_cancel_requests; engine->schedule = execlists_schedule; engine->execlists.tasklet.func = execlists_submission_tasklet; + engine->reset.prepare = execlists_reset_prepare; engine->park = NULL; engine->unpark = NULL; -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 13/18] drm/i915: Allow init_breadcrumbs to be used from irq context
In order to support engine reset from irq (timer) context, we need to be able to re-initialise the breadcrumbs. So we need to promote the plain spin_lock_irq to a safe spin_lock_irqsave. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 0a2128c6b418..ca0b04d9747c 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -846,8 +846,9 @@ static void cancel_fake_irq(struct intel_engine_cs *engine) void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; + unsigned long flags; - spin_lock_irq(&b->irq_lock); + spin_lock_irqsave(&b->irq_lock, flags); /* * Leave the fake_irq timer enabled (if it is running), but clear the @@ -871,7 +872,7 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) */ clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); - spin_unlock_irq(&b->irq_lock); + spin_unlock_irqrestore(&b->irq_lock, flags); } void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine) -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 12/18] drm/i915: Be irqsafe inside reset
As we want to be able to call i915_reset_engine and co from a softirq or timer context, we need to be irqsafe at all timers. So we have to forgo the simple spin_lock_irq for the full spin_lock_irqsave. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8a6acb1d5ad3..a866fe304de1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3041,15 +3041,17 @@ i915_gem_reset_request(struct intel_engine_cs *engine, */ request = i915_gem_find_active_request(engine); if (request) { + unsigned long flags; + i915_gem_context_mark_innocent(request->ctx); dma_fence_set_error(&request->fence, -EAGAIN); /* Rewind the engine to replay the incomplete rq */ - spin_lock_irq(&engine->timeline->lock); + spin_lock_irqsave(&engine->timeline->lock, flags); request = list_prev_entry(request, link); if (&request->link == &engine->timeline->requests) request = NULL; - spin_unlock_irq(&engine->timeline->lock); + spin_unlock_irqrestore(&engine->timeline->lock, flags); } } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 02/18] drm/i915/execlists: Track begin/end of execlists submission sequences
We would like to start doing some bookkeeping at the beginning, between contexts and at the end of execlists submission. We already mark the beginning and end using EXECLISTS_ACTIVE_USER, to provide an indication when the HW is idle. This give us a pair of sequence points we can then expand on for further bookkeeping. Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Francisco Jerez --- drivers/gpu/drm/i915/intel_lrc.c| 42 - drivers/gpu/drm/i915/intel_ringbuffer.h | 11 - 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index f60b61bf8b3b..2d2d33becce3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -374,6 +374,19 @@ execlists_context_status_change(struct i915_request *rq, unsigned long status) status, rq); } +static inline void +execlists_user_begin(struct intel_engine_execlists *execlists, +const struct execlist_port *port) +{ + execlists_set_active_once(execlists, EXECLISTS_ACTIVE_USER); +} + +static inline void +execlists_user_end(struct intel_engine_execlists *execlists) +{ + execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); +} + static inline void execlists_context_schedule_in(struct i915_request *rq) { @@ -711,7 +724,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) spin_unlock_irq(&engine->timeline->lock); if (submit) { - execlists_set_active(execlists, EXECLISTS_ACTIVE_USER); + execlists_user_begin(execlists, execlists->port); execlists_submit_ports(engine); } @@ -742,7 +755,7 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists) port++; } - execlists_clear_active(execlists, EXECLISTS_ACTIVE_USER); + execlists_user_end(execlists); } static void clear_gtiir(struct intel_engine_cs *engine) @@ -873,7 +886,7 @@ static void execlists_submission_tasklet(unsigned long data) { struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; - struct execlist_port * const port = execlists->port; + struct execlist_port *port = execlists->port; struct drm_i915_private *dev_priv = engine->i915; bool fw = false; @@ -1012,9 +1025,19 @@ static void execlists_submission_tasklet(unsigned long data) GEM_BUG_ON(count == 0); if (--count == 0) { + /* +* On the final event corresponding to the +* submission of this context, we expect either +* an element-switch event or a completion +* event (and on completion, the active-idle +* marker). No more preemptions, lite-restore +* or otherwise +*/ GEM_BUG_ON(status & GEN8_CTX_STATUS_PREEMPTED); GEM_BUG_ON(port_isset(&port[1]) && !(status & GEN8_CTX_STATUS_ELEMENT_SWITCH)); + GEM_BUG_ON(!port_isset(&port[1]) && + !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); GEM_BUG_ON(!i915_request_completed(rq)); execlists_context_schedule_out(rq); trace_i915_request_out(rq); @@ -1023,17 +1046,14 @@ static void execlists_submission_tasklet(unsigned long data) GEM_TRACE("%s completed ctx=%d\n", engine->name, port->context_id); - execlists_port_complete(execlists, port); + port = execlists_port_complete(execlists, port); + if (port_isset(port)) + execlists_user_begin(execlists, port); + else + execlists_user_end(execlists); } else { port_set(port, port_pack(rq, count)); } - - /* After the final element, the hw should be idle */ - GEM_BUG_ON(port_count(port) == 0 && - !(status & GEN8_CTX_STATUS_ACTIVE_IDLE)); - if (port_count(port) == 0) - execlists_clear_active(execlists, - EXECLISTS_ACTIVE_USER); } if (head != execlists->csb_head) {
[Intel-gfx] [PATCH 16/18] drm/i915/preemption: Select timeout when scheduling
The choice of preemption timeout is determined by the context from which we trigger the preemption, as such allow the caller to specify the desired timeout. Effectively the other choice would be to use the shortest timeout along the dependency chain. However, given that we would have already triggered preemption for the dependency chain, we can assume that no preemption along that chain is more important than the current request, ergo we need only consider the current timeout. Realising this, we can then pass control of the preemption timeout to the caller for greater flexibility. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c| 2 +- drivers/gpu/drm/i915/i915_request.c| 2 +- drivers/gpu/drm/i915/intel_lrc.c | 5 +- drivers/gpu/drm/i915/intel_ringbuffer.h| 6 +- drivers/gpu/drm/i915/selftests/intel_lrc.c | 106 - 5 files changed, 114 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a866fe304de1..a860d501134e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -482,7 +482,7 @@ static void __fence_set_priority(struct dma_fence *fence, int prio) rcu_read_lock(); if (engine->schedule) - engine->schedule(rq, prio); + engine->schedule(rq, prio, 0); rcu_read_unlock(); } diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 585242831974..cdda3ebd51e2 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1108,7 +1108,7 @@ void __i915_request_add(struct i915_request *request, bool flush_caches) */ rcu_read_lock(); if (engine->schedule) - engine->schedule(request, request->ctx->priority); + engine->schedule(request, request->ctx->priority, 0); rcu_read_unlock(); local_bh_disable(); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index fea275f718f5..06a4815f5f31 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1240,7 +1240,8 @@ pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked) return engine; } -static void execlists_schedule(struct i915_request *request, int prio) +static void execlists_schedule(struct i915_request *request, + int prio, unsigned int timeout) { struct intel_engine_cs *engine; struct i915_dependency *dep, *p; @@ -1336,7 +1337,7 @@ static void execlists_schedule(struct i915_request *request, int prio) if (prio > engine->execlists.queue_priority && i915_sw_fence_done(&pt_to_request(pt)->submit)) - __submit_queue(engine, prio, 0); + __submit_queue(engine, prio, timeout); } spin_unlock_irq(&engine->timeline->lock); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 80c303bb54c8..1e85123534a8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -463,13 +463,15 @@ struct intel_engine_cs { */ void(*submit_request)(struct i915_request *rq); - /* Call when the priority on a request has changed and it and its + /* +* Call when the priority on a request has changed and it and its * dependencies may need rescheduling. Note the request itself may * not be ready to run! * * Called under the struct_mutex. */ - void(*schedule)(struct i915_request *request, int priority); + void(*schedule)(struct i915_request *request, + int priority, unsigned int timeout); /* * Cancel all requests on the hardware, or queued for execution. diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index cd97a6461ec7..1970a4658c5c 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -457,7 +457,7 @@ static int live_late_preempt(void *arg) goto err_wedged; } - engine->schedule(rq, I915_PRIORITY_MAX); + engine->schedule(rq, I915_PRIORITY_MAX, 0); if (!wait_for_spinner(&spin_hi, rq)) { pr_err("High priority context failed to preempt the low priority context\n"); @@ -680,6 +680,109 @@ static int live_preempt_reset(void *arg) return err; } +static int live_late_preempt_timeout(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx_hi, *ctx_lo; + struct spinner spin_hi, spin_lo; + struct intel_engine_cs *engine; + enum intel_engine_id id; +
[Intel-gfx] [PATCH 03/18] drm/i915/execlists: Set queue priority from secondary port
We can refine our current execlists->queue_priority if we inspect ELSP[1] rather than the head of the unsubmitted queue. Currently, we use the unsubmitted queue and say that if a subsequent request is more than important than the current queue, we will rerun the submission tasklet to evaluate the need for preemption. However, we only want to preempt if we need to jump ahead of a currently executing request in ELSP. The second reason for running the submission tasklet is amalgamate requests into the active context on ELSP[0] to avoid a stall when ELSP[0] drains. (Though repeatedly amalgamating requests into the active context and triggering many lite-restore is off question gain, the goal really is to put a context into ELSP[1] to cover the interrupt.) So if instead of looking at the head of the queue, we look at the context in ELSP[1] we can answer both of the questions more accurately -- we don't need to rerun the submission tasklet unless our new request is important enough to feed into, at least, ELSP[1]. References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") Signed-off-by: Chris Wilson Cc: Michał Winiarski Cc: Michel Thierry Cc: Mika Kuoppala Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_lrc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2d2d33becce3..a3fd9683f9d1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -712,7 +712,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) kmem_cache_free(engine->i915->priorities, p); } done: - execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; + execlists->queue_priority = + port != execlists->port ? rq_prio(last) : INT_MIN; execlists->first = rb; if (submit) port_assign(port, last); -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 18/18] drm/i915: Allow user control over preempt timeout on their important context
EGL_NV_realtime_priority? Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_context.c| 22 drivers/gpu/drm/i915/i915_gem_context.h| 13 + drivers/gpu/drm/i915/i915_request.c| 8 ++- drivers/gpu/drm/i915/intel_lrc.c | 2 +- drivers/gpu/drm/i915/selftests/intel_lrc.c | 85 ++ include/uapi/drm/i915_drm.h| 12 + 6 files changed, 139 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 5cfac0255758..dfb0a2b698c3 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -749,6 +749,15 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data, case I915_CONTEXT_PARAM_PRIORITY: args->value = ctx->priority; break; + case I915_CONTEXT_PARAM_PREEMPT_TIMEOUT: + if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION)) + ret = -ENODEV; + else if (args->size) + ret = -EINVAL; + else + args->value = ctx->preempt_timeout; + break; + default: ret = -EINVAL; break; @@ -824,6 +833,19 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data, } break; + case I915_CONTEXT_PARAM_PREEMPT_TIMEOUT: + if (args->size) + ret = -EINVAL; + else if (args->value >= NSEC_PER_SEC) + ret = -EINVAL; + else if (!(to_i915(dev)->caps.scheduler & I915_SCHEDULER_CAP_PREEMPTION)) + ret = -ENODEV; + else if (args->value && !capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else + ctx->preempt_timeout = args->value; + break; + default: ret = -EINVAL; break; diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h index 7854262ddfd9..74d4cadd729e 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.h +++ b/drivers/gpu/drm/i915/i915_gem_context.h @@ -150,6 +150,19 @@ struct i915_gem_context { */ int priority; + /** +* @preempt_timeout: QoS guarantee for the high priority context +* +* Some clients need a guarantee that they will start executing +* within a certain window, even at the expense of others. This entails +* that if a preemption request is not honoured by the active context +* within the timeout, we will reset the GPU to evict the hog and +* run the high priority context instead. +* +* Timeout is stored in nanoseconds; exclusive max of 1s. +*/ + u32 preempt_timeout; + /** ggtt_offset_bias: placement restriction for context objects */ u32 ggtt_offset_bias; diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index cdda3ebd51e2..eae807e56723 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1107,8 +1107,12 @@ void __i915_request_add(struct i915_request *request, bool flush_caches) * run at the earliest possible convenience. */ rcu_read_lock(); - if (engine->schedule) - engine->schedule(request, request->ctx->priority, 0); + if (engine->schedule) { + unsigned int timeout = request->ctx->preempt_timeout; + int priority = request->ctx->priority; + + engine->schedule(request, priority, timeout); + } rcu_read_unlock(); local_bh_disable(); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 06a4815f5f31..e87181f88f96 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1212,7 +1212,7 @@ static void execlists_submit_request(struct i915_request *request) spin_lock_irqsave(&engine->timeline->lock, flags); queue_request(engine, &request->priotree, rq_prio(request)); - submit_queue(engine, rq_prio(request), 0); + submit_queue(engine, rq_prio(request), request->ctx->preempt_timeout); GEM_BUG_ON(!engine->execlists.first); GEM_BUG_ON(list_empty(&request->priotree.link)); diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index 1970a4658c5c..121180b87fd7 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -783,6 +783,90 @@ static int live_late_preempt_timeout(void *arg) goto err_ctx_lo; } +static int live_context_preempt_timeout(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct i915_gem_context *ctx_hi, *ctx_
[Intel-gfx] [PATCH 08/18] drm/i915/selftests: Add basic sanitychecks for execlists
Before adding a new feature to execlists submission, we should endeavour to cover the baseline behaviour with selftests. So start the ball rolling. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin Cc: Mika Kuoppala --- drivers/gpu/drm/i915/intel_lrc.c | 4 + .../gpu/drm/i915/selftests/i915_live_selftests.h | 1 + drivers/gpu/drm/i915/selftests/intel_lrc.c | 506 + 3 files changed, 511 insertions(+) create mode 100644 drivers/gpu/drm/i915/selftests/intel_lrc.c diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6217118633fd..cba1ecda126a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -2693,3 +2693,7 @@ void intel_lr_context_resume(struct drm_i915_private *dev_priv) } } } + +#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) +#include "selftests/intel_lrc.c" +#endif diff --git a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h index 9c76f0305b6a..8bf6aa573226 100644 --- a/drivers/gpu/drm/i915/selftests/i915_live_selftests.h +++ b/drivers/gpu/drm/i915/selftests/i915_live_selftests.h @@ -20,4 +20,5 @@ selftest(evict, i915_gem_evict_live_selftests) selftest(hugepages, i915_gem_huge_page_live_selftests) selftest(contexts, i915_gem_context_live_selftests) selftest(hangcheck, intel_hangcheck_live_selftests) +selftest(execlists, intel_execlists_live_selftests) selftest(guc, intel_guc_live_selftest) diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c new file mode 100644 index ..ef3d739e0a15 --- /dev/null +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -0,0 +1,506 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2018 Intel Corporation + */ + +#include "../i915_selftest.h" + +#include "mock_context.h" + +struct spinner { + struct drm_i915_private *i915; + struct drm_i915_gem_object *hws; + struct drm_i915_gem_object *obj; + u32 *batch; + void *seqno; +}; + +static int spinner_init(struct spinner *spin, struct drm_i915_private *i915) +{ + void *vaddr; + int err; + + GEM_BUG_ON(INTEL_GEN(i915) < 8); + + memset(spin, 0, sizeof(*spin)); + spin->i915 = i915; + + spin->hws = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(spin->hws)) { + err = PTR_ERR(spin->hws); + goto err; + } + + spin->obj = i915_gem_object_create_internal(i915, PAGE_SIZE); + if (IS_ERR(spin->obj)) { + err = PTR_ERR(spin->obj); + goto err_hws; + } + + i915_gem_object_set_cache_level(spin->hws, I915_CACHE_LLC); + vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto err_obj; + } + spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); + + vaddr = i915_gem_object_pin_map(spin->obj, + HAS_LLC(i915) ? I915_MAP_WB : I915_MAP_WC); + if (IS_ERR(vaddr)) { + err = PTR_ERR(vaddr); + goto err_unpin_hws; + } + spin->batch = vaddr; + + return 0; + +err_unpin_hws: + i915_gem_object_unpin_map(spin->hws); +err_obj: + i915_gem_object_put(spin->obj); +err_hws: + i915_gem_object_put(spin->hws); +err: + return err; +} + +static unsigned int seqno_offset(u64 fence) +{ + return offset_in_page(sizeof(u32) * fence); +} + +static u64 hws_address(const struct i915_vma *hws, + const struct i915_request *rq) +{ + return hws->node.start + seqno_offset(rq->fence.context); +} + +static int emit_recurse_batch(struct spinner *spin, + struct i915_request *rq, + u32 arbitration_command) +{ + struct i915_address_space *vm = &rq->ctx->ppgtt->base; + struct i915_vma *hws, *vma; + u32 *batch; + int err; + + vma = i915_vma_instance(spin->obj, vm, NULL); + if (IS_ERR(vma)) + return PTR_ERR(vma); + + hws = i915_vma_instance(spin->hws, vm, NULL); + if (IS_ERR(hws)) + return PTR_ERR(hws); + + err = i915_vma_pin(vma, 0, 0, PIN_USER); + if (err) + return err; + + err = i915_vma_pin(hws, 0, 0, PIN_USER); + if (err) + goto unpin_vma; + + i915_vma_move_to_active(vma, rq, 0); + if (!i915_gem_object_has_active_reference(vma->obj)) { + i915_gem_object_get(vma->obj); + i915_gem_object_set_active_reference(vma->obj); + } + + i915_vma_move_to_active(hws, rq, 0); + if (!i915_gem_object_has_active_reference(hws->obj)) { + i915_gem_object_get(hws->obj); + i915_gem_object_set_active_ref
[Intel-gfx] [PATCH 07/18] drm/i915/execlists: Flush pending preemption events during reset
Catch up with the inflight CSB events, after disabling the tasklet before deciding which request was truly guilty of hanging the GPU. v2: Restore checking of use_csb_mmio on every loop, don't forget old vgpu. Signed-off-by: Chris Wilson Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee --- drivers/gpu/drm/i915/intel_lrc.c | 127 +++ 1 file changed, 87 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5c1324c37549..6217118633fd 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -889,34 +889,14 @@ static void execlists_cancel_requests(struct intel_engine_cs *engine) local_irq_restore(flags); } -/* - * Check the unread Context Status Buffers and manage the submission of new - * contexts to the ELSP accordingly. - */ -static void execlists_submission_tasklet(unsigned long data) +static void process_csb(struct intel_engine_cs *engine) { - struct intel_engine_cs * const engine = (struct intel_engine_cs *)data; struct intel_engine_execlists * const execlists = &engine->execlists; struct execlist_port *port = execlists->port; - struct drm_i915_private *dev_priv = engine->i915; + struct drm_i915_private *i915 = engine->i915; bool fw = false; - /* -* We can skip acquiring intel_runtime_pm_get() here as it was taken -* on our behalf by the request (see i915_gem_mark_busy()) and it will -* not be relinquished until the device is idle (see -* i915_gem_idle_work_handler()). As a precaution, we make sure -* that all ELSP are drained i.e. we have processed the CSB, -* before allowing ourselves to idle and calling intel_runtime_pm_put(). -*/ - GEM_BUG_ON(!dev_priv->gt.awake); - - /* -* Prefer doing test_and_clear_bit() as a two stage operation to avoid -* imposing the cost of a locked atomic transaction when submitting a -* new request (outside of the context-switch interrupt). -*/ - while (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted)) { + do { /* The HWSP contains a (cacheable) mirror of the CSB */ const u32 *buf = &engine->status_page.page_addr[I915_HWS_CSB_BUF0_INDEX]; @@ -924,28 +904,27 @@ static void execlists_submission_tasklet(unsigned long data) if (unlikely(execlists->csb_use_mmio)) { buf = (u32 * __force) - (dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); - execlists->csb_head = -1; /* force mmio read of CSB ptrs */ + (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); + execlists->csb_head = -1; /* force mmio read of CSB */ } /* Clear before reading to catch new interrupts */ clear_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted); smp_mb__after_atomic(); - if (unlikely(execlists->csb_head == -1)) { /* following a reset */ + if (unlikely(execlists->csb_head == -1)) { /* after a reset */ if (!fw) { - intel_uncore_forcewake_get(dev_priv, - execlists->fw_domains); + intel_uncore_forcewake_get(i915, execlists->fw_domains); fw = true; } - head = readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); + head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); tail = GEN8_CSB_WRITE_PTR(head); head = GEN8_CSB_READ_PTR(head); execlists->csb_head = head; } else { const int write_idx = - intel_hws_csb_write_index(dev_priv) - + intel_hws_csb_write_index(i915) - I915_HWS_CSB_BUF0_INDEX; head = execlists->csb_head; @@ -953,8 +932,8 @@ static void execlists_submission_tasklet(unsigned long data) } GEM_TRACE("%s cs-irq head=%d [%d%s], tail=%d [%d%s]\n", engine->name, - head, GEN8_CSB_READ_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?", - tail, GEN8_CSB_WRITE_PTR(readl(dev_priv->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?"); + head, GEN8_CSB_READ_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine,
[Intel-gfx] [PATCH 17/18] drm/i915: Use a preemption timeout to enforce interactivity
Use a liberal timeout of 20ms to ensure that the rendering for an interactive pageflip is started in a timely fashion, and that user interaction is not blocked by GPU, or CPU, hogs. This is at the cost of resetting whoever was blocking the preemption, likely leading to that context/process being banned from submitting future requests. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 3 ++- drivers/gpu/drm/i915/i915_gem.c | 18 ++ drivers/gpu/drm/i915/intel_display.c | 18 +- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 800230ba1c3b..87388feb973d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3150,8 +3150,9 @@ int i915_gem_object_wait(struct drm_i915_gem_object *obj, struct intel_rps_client *rps); int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, unsigned int flags, - int priority); + int priority, unsigned int timeout); #define I915_PRIORITY_DISPLAY I915_PRIORITY_MAX +#define I915_PREEMPTION_TIMEOUT_DISPLAY (20 * 1000 * 1000) /* 20 ms */ int __must_check i915_gem_object_set_to_wc_domain(struct drm_i915_gem_object *obj, bool write); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a860d501134e..3760133ca08e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -469,7 +469,8 @@ i915_gem_object_wait_reservation(struct reservation_object *resv, return timeout; } -static void __fence_set_priority(struct dma_fence *fence, int prio) +static void __fence_set_priority(struct dma_fence *fence, +int prio, unsigned int timeout) { struct i915_request *rq; struct intel_engine_cs *engine; @@ -482,11 +483,12 @@ static void __fence_set_priority(struct dma_fence *fence, int prio) rcu_read_lock(); if (engine->schedule) - engine->schedule(rq, prio, 0); + engine->schedule(rq, prio, timeout); rcu_read_unlock(); } -static void fence_set_priority(struct dma_fence *fence, int prio) +static void fence_set_priority(struct dma_fence *fence, + int prio, unsigned int timeout) { /* Recurse once into a fence-array */ if (dma_fence_is_array(fence)) { @@ -494,16 +496,16 @@ static void fence_set_priority(struct dma_fence *fence, int prio) int i; for (i = 0; i < array->num_fences; i++) - __fence_set_priority(array->fences[i], prio); + __fence_set_priority(array->fences[i], prio, timeout); } else { - __fence_set_priority(fence, prio); + __fence_set_priority(fence, prio, timeout); } } int i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, unsigned int flags, - int prio) + int prio, unsigned int timeout) { struct dma_fence *excl; @@ -518,7 +520,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, return ret; for (i = 0; i < count; i++) { - fence_set_priority(shared[i], prio); + fence_set_priority(shared[i], prio, timeout); dma_fence_put(shared[i]); } @@ -528,7 +530,7 @@ i915_gem_object_wait_priority(struct drm_i915_gem_object *obj, } if (excl) { - fence_set_priority(excl, prio); + fence_set_priority(excl, prio, timeout); dma_fence_put(excl); } return 0; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 415fb8cf2cf4..8ce2019746cc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12788,7 +12788,23 @@ intel_prepare_plane_fb(struct drm_plane *plane, ret = intel_plane_pin_fb(to_intel_plane_state(new_state)); - i915_gem_object_wait_priority(obj, 0, I915_PRIORITY_DISPLAY); + /* +* Reschedule our dependencies, and ensure we run within a timeout. +* +* Note that if the timeout is exceeded, then whoever was running that +* prevented us from acquiring the GPU is declared rogue and reset. An +* unresponsive process will then be banned in order to preserve +* interactivity. Since this can be seen as a bit heavy-handed, we +* select a timeout for when the dropped frames start to become a +* noticeable nuisance for the user (20 ms, i.e. preemption was blocked +* for more than a frame). Note, this is only a timeout for a delay in +* preempting the curre
[Intel-gfx] [PATCH 15/18] drm/i915/execlists: Try preempt-reset from softirq context
When circumstances allow, trying resetting the engine directly from the preemption timeout handler. As this is softirq context, we have to be careful both not to sleep and not to spin on anything we may be interrupting (e.g. the submission tasklet). Signed-off-by: Chris Wilson Cc: Mika Kuoppala Cc: Michał Winiarski CC: Michel Thierry Cc: Jeff McGee Cc: Tvrtko Ursulin --- drivers/gpu/drm/i915/intel_lrc.c | 31 +++- drivers/gpu/drm/i915/selftests/intel_lrc.c | 121 + 2 files changed, 151 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bee8a58f340f..fea275f718f5 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -549,6 +549,33 @@ static void inject_preempt_context(struct intel_engine_cs *engine) execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } +static int try_preempt_reset(struct intel_engine_execlists *execlists) +{ + struct intel_engine_cs *engine = + container_of(execlists, typeof(*engine), execlists); + int err = -EBUSY; + + if (!test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted) && + tasklet_trylock(&execlists->tasklet)) { + unsigned long *lock = &engine->i915->gpu_error.flags; + unsigned int bit = I915_RESET_ENGINE + engine->id; + + if (!test_and_set_bit(bit, lock)) { + tasklet_disable_nosync(&engine->execlists.tasklet); + err = i915_reset_engine(engine, + "preemption time out"); + tasklet_enable(&engine->execlists.tasklet); + + clear_bit(bit, lock); + wake_up_bit(lock, bit); + } + + tasklet_unlock(&execlists->tasklet); + } + + return err; +} + static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) { struct intel_engine_execlists *execlists = @@ -562,7 +589,9 @@ static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT)) return HRTIMER_NORESTART; - queue_work(system_highpri_wq, &execlists->preempt_reset); + if (try_preempt_reset(execlists)) + queue_work(system_highpri_wq, &execlists->preempt_reset); + return HRTIMER_NORESTART; } diff --git a/drivers/gpu/drm/i915/selftests/intel_lrc.c b/drivers/gpu/drm/i915/selftests/intel_lrc.c index a8f2491eab1d..cd97a6461ec7 100644 --- a/drivers/gpu/drm/i915/selftests/intel_lrc.c +++ b/drivers/gpu/drm/i915/selftests/intel_lrc.c @@ -560,6 +560,126 @@ static int live_preempt_timeout(void *arg) return err; } +static void __softirq_begin(void) +{ + local_bh_disable(); +} + +static void __softirq_end(void) +{ + local_bh_enable(); +} + +static void __hardirq_begin(void) +{ + local_irq_disable(); +} + +static void __hardirq_end(void) +{ + local_irq_enable(); +} + +static int live_preempt_reset(void *arg) +{ + struct drm_i915_private *i915 = arg; + struct intel_engine_cs *engine; + struct i915_gem_context *ctx; + enum intel_engine_id id; + struct spinner spin; + int err = -ENOMEM; + + if (!HAS_LOGICAL_RING_PREEMPTION(i915)) + return 0; + + mutex_lock(&i915->drm.struct_mutex); + + if (spinner_init(&spin, i915)) + goto err_unlock; + + ctx= kernel_context(i915); + if (!ctx) + goto err_spin; + + for_each_engine(engine, i915, id) { + static const struct { + const char *name; + void (*critical_section_begin)(void); + void (*critical_section_end)(void); + } phases[] = { + { "softirq", __softirq_begin, __softirq_end }, + { "hardirq", __hardirq_begin, __hardirq_end }, + { } + }; + const typeof(*phases) *p; + + for (p = phases; p->name; p++) { + struct i915_request *rq; + + rq = spinner_create_request(&spin, ctx, engine, + MI_NOOP); + if (IS_ERR(rq)) { + err = PTR_ERR(rq); + goto err_ctx; + } + + i915_request_add(rq); + if (!wait_for_spinner(&spin, rq)) { + i915_gem_set_wedged(i915); + err = -EIO; + goto err_ctx; + } + + /* Flush to give try_preempt_reset a chance */ + do { + tasklet_schedule(&engine->ex
[Intel-gfx] [PATCH 09/18] drm/i915/breadcrumbs: Keep the fake irq armed across reset
Instead of synchronously cancelling the timer and re-enabling it inside the reset callbacks, keep the timer enabled and let it die on its next wakeup if no longer required. This allows intel_engine_reset_breadcrumbs() to be used from an atomic (timer/softirq) context such as required for resetting an engine. It also allows us to react better to the user poking around debugfs for testing missed irqs. Signed-off-by: Chris Wilson Cc: Tvrtko Ursulin Cc: Mika Kuoppala --- drivers/gpu/drm/i915/intel_breadcrumbs.c | 27 +++ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_breadcrumbs.c b/drivers/gpu/drm/i915/intel_breadcrumbs.c index 671a6d61e29d..0a2128c6b418 100644 --- a/drivers/gpu/drm/i915/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/intel_breadcrumbs.c @@ -130,11 +130,12 @@ static void intel_breadcrumbs_hangcheck(struct timer_list *t) static void intel_breadcrumbs_fake_irq(struct timer_list *t) { - struct intel_engine_cs *engine = from_timer(engine, t, - breadcrumbs.fake_irq); + struct intel_engine_cs *engine = + from_timer(engine, t, breadcrumbs.fake_irq); struct intel_breadcrumbs *b = &engine->breadcrumbs; - /* The timer persists in case we cannot enable interrupts, + /* +* The timer persists in case we cannot enable interrupts, * or if we have previously seen seqno/interrupt incoherency * ("missed interrupt" syndrome, better known as a "missed breadcrumb"). * Here the worker will wake up every jiffie in order to kick the @@ -148,6 +149,12 @@ static void intel_breadcrumbs_fake_irq(struct timer_list *t) if (!b->irq_armed) return; + /* If the user has disabled the fake-irq, restore the hangchecking */ + if (!test_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings)) { + mod_timer(&b->hangcheck, wait_timeout()); + return; + } + mod_timer(&b->fake_irq, jiffies + 1); } @@ -840,15 +847,22 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) { struct intel_breadcrumbs *b = &engine->breadcrumbs; - cancel_fake_irq(engine); spin_lock_irq(&b->irq_lock); + /* +* Leave the fake_irq timer enabled (if it is running), but clear the +* bit so that it turns itself off on its next wake up and goes back +* to the long hangcheck interval if still required. +*/ + clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings); + if (b->irq_enabled) irq_enable(engine); else irq_disable(engine); - /* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the + /* +* We set the IRQ_BREADCRUMB bit when we enable the irq presuming the * GPU is active and may have already executed the MI_USER_INTERRUPT * before the CPU is ready to receive. However, the engine is currently * idle (we haven't started it yet), there is no possibility for a @@ -857,9 +871,6 @@ void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine) */ clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted); - if (b->irq_armed) - enable_fake_irq(b); - spin_unlock_irq(&b->irq_lock); } -- 2.16.3 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 14/18] drm/i915/execlists: Force preemption via reset on timeout
Install a timer when trying to preempt on behalf of an important context such that if the active context does not honour the preemption request within the desired timeout, then we reset the GPU to allow the important context to run. v2: Install the timer on scheduling the preempt request; long before we even try to inject preemption into the ELSP, as the tasklet/injection may itself be blocked. v3: Update the guc to handle the preemption/tasklet timer. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_guc_submission.c | 4 ++ drivers/gpu/drm/i915/intel_lrc.c| 82 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 8 ++- drivers/gpu/drm/i915/selftests/intel_lrc.c | 66 +++ 4 files changed, 151 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_guc_submission.c b/drivers/gpu/drm/i915/intel_guc_submission.c index 0e0655430480..d10068579285 100644 --- a/drivers/gpu/drm/i915/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/intel_guc_submission.c @@ -627,6 +627,9 @@ static void complete_preempt_context(struct intel_engine_cs *engine) GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); + hrtimer_try_to_cancel(&execlists->preempt_timer); + execlists_cancel_port_requests(execlists); execlists_unwind_incomplete_requests(execlists); @@ -739,6 +742,7 @@ static void guc_dequeue(struct intel_engine_cs *engine) kmem_cache_free(engine->i915->priorities, p); } done: + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); execlists->queue_priority = rb ? to_priolist(rb)->priority : INT_MIN; execlists->first = rb; if (submit) { diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 731f8de56ea0..bee8a58f340f 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -549,10 +549,50 @@ static void inject_preempt_context(struct intel_engine_cs *engine) execlists_set_active(execlists, EXECLISTS_ACTIVE_PREEMPT); } +static enum hrtimer_restart preempt_timeout(struct hrtimer *hrtimer) +{ + struct intel_engine_execlists *execlists = + container_of(hrtimer, typeof(*execlists), preempt_timer); + + GEM_TRACE("%s\n", + container_of(execlists, + struct intel_engine_cs, + execlists)->name); + + if (!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT)) + return HRTIMER_NORESTART; + + queue_work(system_highpri_wq, &execlists->preempt_reset); + return HRTIMER_NORESTART; +} + +static void preempt_reset(struct work_struct *work) +{ + struct intel_engine_execlists *execlists = + container_of(work, typeof(*execlists), preempt_reset); + struct intel_engine_cs *engine = + container_of(execlists, struct intel_engine_cs, execlists); + + GEM_TRACE("%s\n", engine->name); + + tasklet_disable(&execlists->tasklet); + + execlists->tasklet.func(execlists->tasklet.data); + + if (execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT)) + i915_handle_error(engine->i915, BIT(engine->id), 0, + "preemption time out on %s", engine->name); + + tasklet_enable(&execlists->tasklet); +} + static void complete_preempt_context(struct intel_engine_execlists *execlists) { GEM_BUG_ON(!execlists_is_active(execlists, EXECLISTS_ACTIVE_PREEMPT)); + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); + hrtimer_try_to_cancel(&execlists->preempt_timer); + execlists_cancel_port_requests(execlists); execlists_unwind_incomplete_requests(execlists); @@ -722,6 +762,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) kmem_cache_free(engine->i915->priorities, p); } done: + execlists_clear_active(execlists, EXECLISTS_ACTIVE_PREEMPT_TIMEOUT); execlists->queue_priority = port != execlists->port ? rq_prio(last) : INT_MIN; execlists->first = rb; @@ -1099,16 +1140,38 @@ static void queue_request(struct intel_engine_cs *engine, list_add_tail(&pt->link, &lookup_priolist(engine, pt, prio)->requests); } -static void __submit_queue(struct intel_engine_cs *engine, int prio) +static void __submit_queue(struct intel_engine_cs *engine, + int prio, unsigned int timeout) { - engine->execlists.queue_priority = prio; - tasklet_hi_schedule(&engine->execlists.tasklet); + struct intel_engine_execlists * const execlists = &engine->execlists; + int old = execlists->queue_priority; + + GEM_TRACE("%s prio=%d (previous=%d)\n", engine->name, prio, old); + + i
Re: [Intel-gfx] [PATCH v12 05/17] drm/i915/guc/slpc: Add SLPC communication interfaces
On 3/30/2018 7:07 PM, Michal Wajdeczko wrote: On Fri, 30 Mar 2018 10:31:50 +0200, Sagar Arun Kamble wrote: diff --git a/drivers/gpu/drm/i915/intel_guc_slpc.h b/drivers/gpu/drm/i915/intel_guc_slpc.h index 66c76fe..81250c0 100644 --- a/drivers/gpu/drm/i915/intel_guc_slpc.h +++ b/drivers/gpu/drm/i915/intel_guc_slpc.h @@ -6,6 +6,8 @@ #ifndef _INTEL_GUC_SLPC_H_ #define _INTEL_GUC_SLPC_H_ +#include Please use "" instead of <> Yes. will hopefully not forget this next time :) + struct intel_guc_slpc { }; diff --git a/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h new file mode 100644 index 000..9400af4 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_guc_slpc_fwif.h @@ -0,0 +1,211 @@ +/* + * SPDX-License-Identifier: MIT + * + * Copyright © 2015-2018 Intel Corporation + */ +#ifndef _INTEL_GUC_SLPC_FWIF_H_ +#define _INTEL_GUC_SLPC_FWIF_H_ + +#include + +enum slpc_status { s/slpc_status/intel_guc_slpc_status I have done this because of following reasons: 1. GuC SLPC interface file shared by firmware team names enums/structs as SLPM_* or SLPM_KMD_*. i understand that this isn't strict requirement. :) 2. INTEL_GUC_STATUS|EVENT|PARAM_* becomes more than 80 chars for some values 3. I wanted intel_guc_slpc_fwif.h to be included only in intel_guc_slpc.c from where we can export functions as intel_guc_slpc_* static functions in intel_guc_slpc.c are named as slpc_*. In my series, point 3 above is not done but that was intent. There is access to SLPC enums from debugfs.c. Would consolidate all in intel_guc_slpc.c and export. Does this plan look good? + SLPC_STATUS_OK = 0, + SLPC_STATUS_ERROR = 1, + SLPC_STATUS_ILLEGAL_COMMAND = 2, + SLPC_STATUS_INVALID_ARGS = 3, + SLPC_STATUS_INVALID_PARAMS = 4, + SLPC_STATUS_INVALID_DATA = 5, + SLPC_STATUS_OUT_OF_RANGE = 6, + SLPC_STATUS_NOT_SUPPORTED = 7, + SLPC_STATUS_NOT_IMPLEMENTED = 8, + SLPC_STATUS_NO_DATA = 9, + SLPC_STATUS_EVENT_NOT_REGISTERED = 10, + SLPC_STATUS_REGISTER_LOCKED = 11, + SLPC_STATUS_TEMPORARILY_UNAVAILABLE = 12, + SLPC_STATUS_VALUE_ALREADY_SET = 13, + SLPC_STATUS_VALUE_ALREADY_UNSET = 14, + SLPC_STATUS_VALUE_NOT_CHANGED = 15, + SLPC_STATUS_MEMIO_ERROR = 16, + SLPC_STATUS_EVENT_QUEUED_REQ_DPC = 17, + SLPC_STATUS_EVENT_QUEUED_NOREQ_DPC = 18, + SLPC_STATUS_NO_EVENT_QUEUED = 19, + SLPC_STATUS_OUT_OF_SPACE = 20, + SLPC_STATUS_TIMEOUT = 21, + SLPC_STATUS_NO_LOCK = 22, + SLPC_STATUS_MAX s/SLPC_STATUS/INTEL_GUC_SLPC_STATUS +}; + +enum slpc_event_id { s/slpc_event_id/intel_guc_slpc_event + SLPC_EVENT_RESET = 0, + SLPC_EVENT_SHUTDOWN = 1, + SLPC_EVENT_PLATFORM_INFO_CHANGE = 2, + SLPC_EVENT_DISPLAY_MODE_CHANGE = 3, + SLPC_EVENT_FLIP_COMPLETE = 4, + SLPC_EVENT_QUERY_TASK_STATE = 5, + SLPC_EVENT_PARAMETER_SET = 6, + SLPC_EVENT_PARAMETER_UNSET = 7, s/SLPC_EVENT/INTEL_GUC_SLPC_EVENT +}; + +enum slpc_param_id { s/slpc_param_id/intel_guc_slpc_param + SLPC_PARAM_TASK_ENABLE_GTPERF = 0, + SLPC_PARAM_TASK_DISABLE_GTPERF = 1, + SLPC_PARAM_TASK_ENABLE_BALANCER = 2, + SLPC_PARAM_TASK_DISABLE_BALANCER = 3, + SLPC_PARAM_TASK_ENABLE_DCC = 4, + SLPC_PARAM_TASK_DISABLE_DCC = 5, + SLPC_PARAM_GLOBAL_MIN_GT_UNSLICE_FREQ_MHZ = 6, + SLPC_PARAM_GLOBAL_MAX_GT_UNSLICE_FREQ_MHZ = 7, + SLPC_PARAM_GLOBAL_MIN_GT_SLICE_FREQ_MHZ = 8, + SLPC_PARAM_GLOBAL_MAX_GT_SLICE_FREQ_MHZ = 9, + SLPC_PARAM_GTPERF_THRESHOLD_MAX_FPS = 10, + SLPC_PARAM_GLOBAL_DISABLE_GT_FREQ_MANAGEMENT = 11, + SLPC_PARAM_GTPERF_ENABLE_FRAMERATE_STALLING = 12, + SLPC_PARAM_GLOBAL_DISABLE_RC6_MODE_CHANGE = 13, + SLPC_PARAM_GLOBAL_OC_UNSLICE_FREQ_MHZ = 14, + SLPC_PARAM_GLOBAL_OC_SLICE_FREQ_MHZ = 15, + SLPC_PARAM_GLOBAL_ENABLE_IA_GT_BALANCING = 16, + SLPC_PARAM_GLOBAL_ENABLE_ADAPTIVE_BURST_TURBO = 17, + SLPC_PARAM_GLOBAL_ENABLE_EVAL_MODE = 18, + SLPC_PARAM_GLOBAL_ENABLE_BALANCER_IN_NON_GAMING_MODE = 19, s/SLPC_PARAM/INTEL_GUC_SLPC_PARAM + SLPC_MAX_PARAM, + SLPC_KMD_MAX_PARAM = 32, hmm, do we really need these two ? please drop or maybe these are related to SLPC_MAX_OVERRIDE_PARAMETERS ? Ok. Will drop SLPC_KMD_MAX_PARAM. There are total 192 params (MAX_OVERRIDE_PARAMS) out of which 32 (KMD_MAX_PARAM) params can be exposed to KMD, but currently only params till MAX_PARAM < 32 are exported. +}; + +enum slpc_global_state { s/slpc_global_state/intel_guc_slpc_state + SLPC_GLOBAL_STATE_NOT_RUNNING = 0, + SLPC_GLOBAL_STATE_INITIALIZING = 1, + SLPC_GLOBAL_STATE_RESETTING = 2, + SLPC_GLOBAL_STATE_RUNNING = 3, + SLPC_GLOBAL_STATE_SHUTTING_DOWN = 4, + SLPC_GLOBAL_STATE_ERROR = 5 s/SLPC_GLOBAL_STATE/INTEL_GUC_SLPC_STATE +}; + +enum slpc_platform_sku { + SLPC_PLATFORM_SKU_UNDEFINED = 0, + SLPC_PLATFORM_SKU_ULX = 1, + SLPC_PLATFORM_SKU_ULT = 2, + SLPC_PLATFORM_SKU_T = 3, + SLPC_PLATFORM_SKU_MOBL = 4, + SLPC_PLATFORM_SKU_DT = 5, + SLPC_PLATFORM
[Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context
== Series Details == Series: series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context URL : https://patchwork.freedesktop.org/series/40961/ State : warning == Summary == $ dim checkpatch origin/drm-tip 33a1831a25b2 drm/i915/selftests: Avoid repeatedly harming the same innocent context 17fe6b08c0bf drm/i915/execlists: Track begin/end of execlists submission sequences becb341ba47d drm/i915/execlists: Set queue priority from secondary port -:25: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line) #25: References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") -:25: ERROR:GIT_COMMIT_ID: Please use git commit description style 'commit <12+ chars of sha1> ("")' - ie: 'commit f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports")' #25: References: f6322eddaff7 ("drm/i915/preemption: Allow preemption between submission ports") total: 1 errors, 1 warnings, 0 checks, 9 lines checked 13502d2881e0 drm/i915/execlists: Refactor out complete_preempt_context() 271227fad5d5 drm/i915: Move engine reset prepare/finish to backends 335269c0d938 drm/i915: Split execlists/guc reset prepartions fc3bcbc4574d drm/i915/execlists: Flush pending preemption events during reset -:69: WARNING:LONG_LINE: line over 100 characters #69: FILE: drivers/gpu/drm/i915/intel_lrc.c:907: + (i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_BUF_LO(engine, 0))); -:87: WARNING:LONG_LINE: line over 100 characters #87: FILE: drivers/gpu/drm/i915/intel_lrc.c:921: + head = readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine))); -:104: WARNING:LONG_LINE: line over 100 characters #104: FILE: drivers/gpu/drm/i915/intel_lrc.c:935: + head, GEN8_CSB_READ_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?", -:105: WARNING:LONG_LINE: line over 100 characters #105: FILE: drivers/gpu/drm/i915/intel_lrc.c:936: + tail, GEN8_CSB_WRITE_PTR(readl(i915->regs + i915_mmio_reg_offset(RING_CONTEXT_STATUS_PTR(engine, fw ? "" : "?"); total: 0 errors, 4 warnings, 0 checks, 192 lines checked 5cf71d272c49 drm/i915/selftests: Add basic sanitychecks for execlists -:43: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating? #43: new file mode 100644 -:254: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'W' - possible side-effects? #254: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:207: +#define wedge_on_timeout(W, DEV, TIMEOUT) \ + for (__init_wedge((W), (DEV), (TIMEOUT), __builtin_return_address(0)); \ +(W)->i915; \ +__fini_wedge((W))) total: 0 errors, 1 warnings, 1 checks, 518 lines checked 5cc163689f97 drm/i915/breadcrumbs: Keep the fake irq armed across reset 520b029fa706 drm/i915: Combine tasklet_kill and tasklet_disable -:39: WARNING:MEMORY_BARRIER: memory barrier without comment #39: FILE: drivers/gpu/drm/i915/intel_lrc.c:1755: + smp_mb(); total: 0 errors, 1 warnings, 0 checks, 26 lines checked f719516f05ff drm/i915: Stop parking the signaler around reset 33aa7c8491c9 drm/i915: Be irqsafe inside reset 6ddb32ce734e drm/i915: Allow init_breadcrumbs to be used from irq context 7f3c5b702350 drm/i915/execlists: Force preemption via reset on timeout -:228: ERROR:SPACING: spaces required around that '=' (ctx:VxW) #228: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:515: + ctx= kernel_context(i915); ^ total: 1 errors, 0 warnings, 0 checks, 241 lines checked 9003b1d0a64a drm/i915/execlists: Try preempt-reset from softirq context -:115: ERROR:SPACING: spaces required around that '=' (ctx:VxW) #115: FILE: drivers/gpu/drm/i915/selftests/intel_lrc.c:600: + ctx= kernel_context(i915); ^ total: 1 errors, 0 warnings, 0 checks, 176 lines checked b85e8d84cd91 drm/i915/preemption: Select timeout when scheduling c96747bc6976 drm/i915: Use a preemption timeout to enforce interactivity 7161c21aa08a drm/i915: Allow user control over preempt timeout on their important context ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context
== Series Details == Series: series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context URL : https://patchwork.freedesktop.org/series/40961/ State : success == Summary == Series 40961v1 series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context https://patchwork.freedesktop.org/api/1.0/series/40961/revisions/1/mbox/ Known issues: Test kms_pipe_crc_basic: Subgroup nonblocking-crc-pipe-b-frame-sequence: pass -> FAIL (fi-skl-guc) fdo#103191 fdo#103191 https://bugs.freedesktop.org/show_bug.cgi?id=103191 fi-bdw-5557u total:285 pass:264 dwarn:0 dfail:0 fail:0 skip:21 time:431s fi-bdw-gvtdvmtotal:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:441s fi-blb-e6850 total:285 pass:220 dwarn:1 dfail:0 fail:0 skip:64 time:379s fi-bsw-n3050 total:285 pass:239 dwarn:0 dfail:0 fail:0 skip:46 time:537s fi-bwr-2160 total:285 pass:180 dwarn:0 dfail:0 fail:0 skip:105 time:298s fi-bxt-dsi total:285 pass:255 dwarn:0 dfail:0 fail:0 skip:30 time:511s fi-bxt-j4205 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:510s fi-byt-j1900 total:285 pass:250 dwarn:0 dfail:0 fail:0 skip:35 time:521s fi-byt-n2820 total:285 pass:246 dwarn:0 dfail:0 fail:0 skip:39 time:510s fi-cfl-8700k total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:416s fi-cfl-s3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:561s fi-cfl-u total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:512s fi-cnl-y3total:285 pass:259 dwarn:0 dfail:0 fail:0 skip:26 time:590s fi-elk-e7500 total:285 pass:225 dwarn:1 dfail:0 fail:0 skip:59 time:425s fi-gdg-551 total:285 pass:176 dwarn:0 dfail:0 fail:1 skip:108 time:315s fi-glk-1 total:285 pass:257 dwarn:0 dfail:0 fail:0 skip:28 time:539s fi-hsw-4770 total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:404s fi-ilk-650 total:285 pass:225 dwarn:0 dfail:0 fail:0 skip:60 time:424s fi-ivb-3520m total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:459s fi-ivb-3770 total:285 pass:252 dwarn:0 dfail:0 fail:0 skip:33 time:430s fi-kbl-7500u total:285 pass:260 dwarn:1 dfail:0 fail:0 skip:24 time:472s fi-kbl-7567u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:460s fi-kbl-r total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:506s fi-pnv-d510 total:285 pass:219 dwarn:1 dfail:0 fail:0 skip:65 time:657s fi-skl-6260u total:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:446s fi-skl-6600u total:285 pass:258 dwarn:0 dfail:0 fail:0 skip:27 time:532s fi-skl-6700k2total:285 pass:261 dwarn:0 dfail:0 fail:0 skip:24 time:507s fi-skl-6770hqtotal:285 pass:265 dwarn:0 dfail:0 fail:0 skip:20 time:511s fi-skl-guc total:285 pass:256 dwarn:0 dfail:0 fail:1 skip:28 time:429s fi-skl-gvtdvmtotal:285 pass:262 dwarn:0 dfail:0 fail:0 skip:23 time:444s fi-snb-2520m total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:575s fi-snb-2600 total:285 pass:245 dwarn:0 dfail:0 fail:0 skip:40 time:395s Blacklisted hosts: fi-cnl-psr total:285 pass:256 dwarn:3 dfail:0 fail:0 skip:26 time:525s fi-glk-j4005 total:285 pass:256 dwarn:0 dfail:0 fail:0 skip:29 time:483s 335ef9849310af26d65c54f7d2d2e9dcbce238b9 drm-tip: 2018y-03m-30d-09h-08m-40s UTC integration manifest 7161c21aa08a drm/i915: Allow user control over preempt timeout on their important context c96747bc6976 drm/i915: Use a preemption timeout to enforce interactivity b85e8d84cd91 drm/i915/preemption: Select timeout when scheduling 9003b1d0a64a drm/i915/execlists: Try preempt-reset from softirq context 7f3c5b702350 drm/i915/execlists: Force preemption via reset on timeout 6ddb32ce734e drm/i915: Allow init_breadcrumbs to be used from irq context 33aa7c8491c9 drm/i915: Be irqsafe inside reset f719516f05ff drm/i915: Stop parking the signaler around reset 520b029fa706 drm/i915: Combine tasklet_kill and tasklet_disable 5cc163689f97 drm/i915/breadcrumbs: Keep the fake irq armed across reset 5cf71d272c49 drm/i915/selftests: Add basic sanitychecks for execlists fc3bcbc4574d drm/i915/execlists: Flush pending preemption events during reset 335269c0d938 drm/i915: Split execlists/guc reset prepartions 271227fad5d5 drm/i915: Move engine reset prepare/finish to backends 13502d2881e0 drm/i915/execlists: Refactor out complete_preempt_context() becb341ba47d drm/i915/execlists: Set queue priority from secondary port 17fe6b08c0bf drm/i915/execlists: Track begin/end of execlists submission sequences 33a1831a25b2 drm/i915/selftests: Avoid repeatedly harming the same innocent conte
[Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context
== Series Details == Series: series starting with [01/18] drm/i915/selftests: Avoid repeatedly harming the same innocent context URL : https://patchwork.freedesktop.org/series/40961/ State : failure == Summary == Possible new issues: Test gem_ctx_param: Subgroup invalid-param-get: pass -> FAIL (shard-apl) pass -> FAIL (shard-hsw) pass -> FAIL (shard-snb) Subgroup invalid-param-set: pass -> FAIL (shard-apl) pass -> FAIL (shard-hsw) pass -> FAIL (shard-snb) Test gem_mmap_wc: Subgroup set-cache-level: pass -> SKIP (shard-snb) Test kms_cursor_crc: Subgroup cursor-64x64-dpms: pass -> FAIL (shard-snb) Known issues: Test kms_flip: Subgroup 2x-dpms-vs-vblank-race: fail -> PASS (shard-hsw) fdo#103060 Subgroup 2x-flip-vs-expired-vblank-interruptible: fail -> PASS (shard-hsw) fdo#102887 Subgroup flip-vs-blocking-wf-vblank: fail -> PASS (shard-hsw) fdo#100368 Subgroup flip-vs-panning-vs-hang-interruptible: dmesg-warn -> PASS (shard-snb) fdo#103821 Test kms_sysfs_edid_timing: pass -> WARN (shard-apl) fdo#100047 fdo#103060 https://bugs.freedesktop.org/show_bug.cgi?id=103060 fdo#102887 https://bugs.freedesktop.org/show_bug.cgi?id=102887 fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368 fdo#103821 https://bugs.freedesktop.org/show_bug.cgi?id=103821 fdo#100047 https://bugs.freedesktop.org/show_bug.cgi?id=100047 shard-apltotal:3496 pass:1830 dwarn:1 dfail:0 fail:9 skip:1655 time:12887s shard-hswtotal:3496 pass:1782 dwarn:1 dfail:0 fail:3 skip:1709 time:11615s shard-snbtotal:3496 pass:1371 dwarn:1 dfail:0 fail:8 skip:2116 time:7027s Blacklisted hosts: shard-kbltotal:3496 pass:1955 dwarn:1 dfail:0 fail:10 skip:1530 time:9345s == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_8550/shards.html ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH v1] drm/i915: Add Exec param to control data port coherency.
The patch adds a parameter to control the data port coherency functionality on a per-exec call basis. When data port coherency flag value is different than what it was in previous call for the context, a command to switch data port coherency state is added before the buffer to be executed. Rationale: The OpenCL driver develpers requested a functionality to control cache coherency at data port level. Keeping the coherency at that level is disabled by default due to its performance costs. OpenCL driver is planning to enable it for a small subset of submissions, when such functionality is required. Below are answers to basic question explaining background of the functionality and reasoning for the proposed implementation: 1. Why do we need a coherency enable/disable switch for memory that is shared between CPU and GEN (GPU)? Memory coherency between CPU and GEN, while being a great feature that enables CL_MEM_SVM_FINE_GRAIN_BUFFER OCL capability on Intel GEN architecture, adds overhead related to tracking (snooping) memory inside different cache units (L1$, L2$, L3$, LLC$, etc.). At the same time, minority of modern OCL applications actually use CL_MEM_SVM_FINE_GRAIN_BUFFER (and hence require memory coherency between CPU and GPU). The goal of coherency enable/disable switch is to remove overhead of memory coherency when memory coherency is not needed. 2. Why do we need a global coherency switch? In order to support I/O commands from within EUs (Execution Units), Intel GEN ISA (GEN Instruction Set Assembly) contains dedicated "send" instructions. These send instructions provide several addressing models. One of these addressing models (named "stateless") provides most flexible I/O using plain virtual addresses (as opposed to buffer_handle+offset models). This "stateless" model is similar to regular memory load/store operations available on typical CPUs. Since this model provides I/O using arbitrary virtual addresses, it enables algorithmic designs that are based on pointer-to-pointer (e.g. buffer of pointers) concepts. For instance, it allows creating tree-like data structures such as: | NODE1 | | uint64_t data | +| | NODE* | NODE*| ++---+ / \ /\ | NODE2 || NODE3 | | uint64_t data || uint64_t data | +|+| | NODE* | NODE*|| NODE* | NODE*| ++---+++---+ Please note that pointers inside such structures can point to memory locations in different OCL allocations - e.g. NODE1 and NODE2 can reside in one OCL allocation while NODE3 resides in a completely separate OCL allocation. Additionally, such pointers can be shared with CPU (i.e. using SVM - Shared Virtual Memory feature). Using pointers from different allocations doesn't affect the stateless addressing model which even allows scattered reading from different allocations at the same time (i.e. by utilizing SIMD-nature of send instructions). When it comes to coherency programming, send instructions in stateless model can be encoded (at ISA level) to either use or disable coherency. However, for generic OCL applications (such as example with tree-like data structure), OCL compiler is not able to determine origin of memory pointed to by an arbitrary pointer - i.e. is not able to track given pointer back to a specific allocation. As such, it's not able to decide whether coherency is needed or not for specific pointer (or for specific I/O instruction). As a result, compiler encodes all stateless sends as coherent (doing otherwise would lead to functional issues resulting from data corruption). Please note that it would be possible to workaround this (e.g. based on allocations map and pointer bounds checking prior to each I/O instruction) but the performance cost of such workaround would be many times greater than the cost of keeping coherency always enabled. As such, enabling/disabling memory coherency at GEN ISA level is not feasible and alternative method is needed. Such alternative solution is to have a global coherency switch that allows disabling coherency for single (though entire) GPU submission. This is beneficial because this way we: * can enable (and pay for) coherency only in submissions that actually need coherency (submissions that use CL_MEM_SVM_FINE_GRAIN_BUFFER resources) * don't care about coherency at GEN ISA granularity (no performance impact) 3. Will coherency switch be used frequently? There are scenarios that will require frequent toggling of the coherency switch. E.g. an application has two OCL compute kernels: kern_master and kern_worker. kern_master uses, concurrently with CPU, some fine grain SVM resources (CL_MEM_SVM_F