xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/i915/i915_utils.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: MIT
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright © 2019 Intel Corporation
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <drm/drm_drv.h>
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include "i915_drv.h"
9*4882a593Smuzhiyun #include "i915_utils.h"
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details."
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun void
__i915_printk(struct drm_i915_private * dev_priv,const char * level,const char * fmt,...)14*4882a593Smuzhiyun __i915_printk(struct drm_i915_private *dev_priv, const char *level,
15*4882a593Smuzhiyun 	      const char *fmt, ...)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun 	static bool shown_bug_once;
18*4882a593Smuzhiyun 	struct device *kdev = dev_priv->drm.dev;
19*4882a593Smuzhiyun 	bool is_error = level[1] <= KERN_ERR[1];
20*4882a593Smuzhiyun 	bool is_debug = level[1] == KERN_DEBUG[1];
21*4882a593Smuzhiyun 	struct va_format vaf;
22*4882a593Smuzhiyun 	va_list args;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun 	if (is_debug && !drm_debug_enabled(DRM_UT_DRIVER))
25*4882a593Smuzhiyun 		return;
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 	va_start(args, fmt);
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun 	vaf.fmt = fmt;
30*4882a593Smuzhiyun 	vaf.va = &args;
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun 	if (is_error)
33*4882a593Smuzhiyun 		dev_printk(level, kdev, "%pV", &vaf);
34*4882a593Smuzhiyun 	else
35*4882a593Smuzhiyun 		dev_printk(level, kdev, "[" DRM_NAME ":%ps] %pV",
36*4882a593Smuzhiyun 			   __builtin_return_address(0), &vaf);
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 	va_end(args);
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun 	if (is_error && !shown_bug_once) {
41*4882a593Smuzhiyun 		/*
42*4882a593Smuzhiyun 		 * Ask the user to file a bug report for the error, except
43*4882a593Smuzhiyun 		 * if they may have caused the bug by fiddling with unsafe
44*4882a593Smuzhiyun 		 * module parameters.
45*4882a593Smuzhiyun 		 */
46*4882a593Smuzhiyun 		if (!test_taint(TAINT_USER))
47*4882a593Smuzhiyun 			dev_notice(kdev, "%s", FDO_BUG_MSG);
48*4882a593Smuzhiyun 		shown_bug_once = true;
49*4882a593Smuzhiyun 	}
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
add_taint_for_CI(struct drm_i915_private * i915,unsigned int taint)52*4882a593Smuzhiyun void add_taint_for_CI(struct drm_i915_private *i915, unsigned int taint)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun 	__i915_printk(i915, KERN_NOTICE, "CI tainted:%#x by %pS\n",
55*4882a593Smuzhiyun 		      taint, (void *)_RET_IP_);
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 	/* Failures that occur during fault injection testing are expected */
58*4882a593Smuzhiyun 	if (!i915_error_injected())
59*4882a593Smuzhiyun 		__add_taint_for_CI(taint);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_DRM_I915_DEBUG)
63*4882a593Smuzhiyun static unsigned int i915_probe_fail_count;
64*4882a593Smuzhiyun 
__i915_inject_probe_error(struct drm_i915_private * i915,int err,const char * func,int line)65*4882a593Smuzhiyun int __i915_inject_probe_error(struct drm_i915_private *i915, int err,
66*4882a593Smuzhiyun 			      const char *func, int line)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	if (i915_probe_fail_count >= i915_modparams.inject_probe_failure)
69*4882a593Smuzhiyun 		return 0;
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun 	if (++i915_probe_fail_count < i915_modparams.inject_probe_failure)
72*4882a593Smuzhiyun 		return 0;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	__i915_printk(i915, KERN_INFO,
75*4882a593Smuzhiyun 		      "Injecting failure %d at checkpoint %u [%s:%d]\n",
76*4882a593Smuzhiyun 		      err, i915_modparams.inject_probe_failure, func, line);
77*4882a593Smuzhiyun 	i915_modparams.inject_probe_failure = 0;
78*4882a593Smuzhiyun 	return err;
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
i915_error_injected(void)81*4882a593Smuzhiyun bool i915_error_injected(void)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	return i915_probe_fail_count && !i915_modparams.inject_probe_failure;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun #endif
87*4882a593Smuzhiyun 
cancel_timer(struct timer_list * t)88*4882a593Smuzhiyun void cancel_timer(struct timer_list *t)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	if (!READ_ONCE(t->expires))
91*4882a593Smuzhiyun 		return;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	del_timer(t);
94*4882a593Smuzhiyun 	WRITE_ONCE(t->expires, 0);
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun 
set_timer_ms(struct timer_list * t,unsigned long timeout)97*4882a593Smuzhiyun void set_timer_ms(struct timer_list *t, unsigned long timeout)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun 	if (!timeout) {
100*4882a593Smuzhiyun 		cancel_timer(t);
101*4882a593Smuzhiyun 		return;
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	timeout = msecs_to_jiffies(timeout);
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	/*
107*4882a593Smuzhiyun 	 * Paranoia to make sure the compiler computes the timeout before
108*4882a593Smuzhiyun 	 * loading 'jiffies' as jiffies is volatile and may be updated in
109*4882a593Smuzhiyun 	 * the background by a timer tick. All to reduce the complexity
110*4882a593Smuzhiyun 	 * of the addition and reduce the risk of losing a jiffie.
111*4882a593Smuzhiyun 	 */
112*4882a593Smuzhiyun 	barrier();
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	/* Keep t->expires = 0 reserved to indicate a canceled timer. */
115*4882a593Smuzhiyun 	mod_timer(t, jiffies + timeout ?: 1);
116*4882a593Smuzhiyun }
117