drm/i915/guc: Connect reset modparam updates to GuC policy flags
authorJohn Harrison <John.C.Harrison@Intel.com>
Tue, 27 Jul 2021 00:23:36 +0000 (17:23 -0700)
committerJohn Harrison <John.C.Harrison@Intel.com>
Wed, 28 Jul 2021 00:32:06 +0000 (17:32 -0700)
Changing the reset module parameter has no effect on a running GuC.
The corresponding entry in the ADS must be updated and then the GuC
informed via a Host2GuC message.

The new debugfs interface to module parameters allows this to happen.
However, connecting the parameter data address back to anything useful
is messy. One option would be to pass a new private data structure
address through instead of just the parameter pointer. However, that
means having a new (and different) data structure for each parameter
and a new (and different) write function for each parameter. This
method keeps everything generic by instead using a string lookup on
the directory entry name.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210727002348.97202-22-matthew.brost@intel.com
drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
drivers/gpu/drm/i915/i915_debugfs_params.c

index 60b73625f686a6e0f7323f57b7cfea903e6e9d85..7797766c56a922659a514452c7e78bcc74a5ff23 100644 (file)
@@ -99,7 +99,7 @@ static int guc_action_policies_update(struct intel_guc *guc, u32 policy_offset)
                policy_offset
        };
 
-       return intel_guc_send(guc, action, ARRAY_SIZE(action));
+       return intel_guc_send_busy_loop(guc, action, ARRAY_SIZE(action), 0, true);
 }
 
 int intel_guc_global_policies_update(struct intel_guc *guc)
index 4e2b077692cb5ace70cd5ea64fabd17df9738ef1..20424275d41ebf177f4d37157721e95d4f3f3321 100644 (file)
@@ -6,9 +6,21 @@
 #include <linux/kernel.h>
 
 #include "i915_debugfs_params.h"
+#include "gt/intel_gt.h"
+#include "gt/uc/intel_guc.h"
 #include "i915_drv.h"
 #include "i915_params.h"
 
+#define MATCH_DEBUGFS_NODE_NAME(_file, _name) \
+       (strcmp((_file)->f_path.dentry->d_name.name, (_name)) == 0)
+
+#define GET_I915(i915, name, ptr)      \
+       do {    \
+               struct i915_params *params;     \
+               params = container_of(((void *)(ptr)), typeof(*params), name);  \
+               (i915) = container_of(params, typeof(*(i915)), params); \
+       } while (0)
+
 /* int param */
 static int i915_param_int_show(struct seq_file *m, void *data)
 {
@@ -24,6 +36,16 @@ static int i915_param_int_open(struct inode *inode, struct file *file)
        return single_open(file, i915_param_int_show, inode->i_private);
 }
 
+static int notify_guc(struct drm_i915_private *i915)
+{
+       int ret = 0;
+
+       if (intel_uc_uses_guc_submission(&i915->gt.uc))
+               ret = intel_guc_global_policies_update(&i915->gt.uc.guc);
+
+       return ret;
+}
+
 static ssize_t i915_param_int_write(struct file *file,
                                    const char __user *ubuf, size_t len,
                                    loff_t *offp)
@@ -81,8 +103,10 @@ static ssize_t i915_param_uint_write(struct file *file,
                                     const char __user *ubuf, size_t len,
                                     loff_t *offp)
 {
+       struct drm_i915_private *i915;
        struct seq_file *m = file->private_data;
        unsigned int *value = m->private;
+       unsigned int old = *value;
        int ret;
 
        ret = kstrtouint_from_user(ubuf, len, 0, value);
@@ -95,6 +119,14 @@ static ssize_t i915_param_uint_write(struct file *file,
                        *value = b;
        }
 
+       if (!ret && MATCH_DEBUGFS_NODE_NAME(file, "reset")) {
+               GET_I915(i915, reset, value);
+
+               ret = notify_guc(i915);
+               if (ret)
+                       *value = old;
+       }
+
        return ret ?: len;
 }