2022-12-24 22:54:40

by Deepak R Varma

[permalink] [raw]
Subject: [PATCH] drm/i915: convert i915_active.count from atomic_t to refcount_t

The refcount_* APIs are designed to address known issues with the
atomic_t APIs for reference counting. They provide following distinct
advantages:
- protect the reference counters from overflow/underflow
- avoid use-after-free errors
- provide improved memory ordering guarantee schemes
- neater and safer.
Hence, convert the atomic_t count member variable and associated
atomic_*() API calls to equivalent refcount_t type and refcount_*() API
calls.

This patch proposal address the following warnings generated by
the atomic_as_refcounter.cocci coccinelle script
atomic_add_unless

Signed-off-by: Deepak R Varma <[email protected]>
---
Please note: Proposed changes are compile tested only.

drivers/gpu/drm/i915/i915_active.c | 24 +++++++++++++-----------
drivers/gpu/drm/i915/i915_active.h | 6 +++---
drivers/gpu/drm/i915/i915_active_types.h | 4 ++--
3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c
index 7412abf166a8..4a8d873b4347 100644
--- a/drivers/gpu/drm/i915/i915_active.c
+++ b/drivers/gpu/drm/i915/i915_active.c
@@ -133,7 +133,7 @@ __active_retire(struct i915_active *ref)
GEM_BUG_ON(i915_active_is_idle(ref));

/* return the unused nodes to our slabcache -- flushing the allocator */
- if (!atomic_dec_and_lock_irqsave(&ref->count, &ref->tree_lock, flags))
+ if (!refcount_dec_and_lock_irqsave(&ref->count, &ref->tree_lock, &flags))
return;

GEM_BUG_ON(rcu_access_pointer(ref->excl.fence));
@@ -179,8 +179,8 @@ active_work(struct work_struct *wrk)
{
struct i915_active *ref = container_of(wrk, typeof(*ref), work);

- GEM_BUG_ON(!atomic_read(&ref->count));
- if (atomic_add_unless(&ref->count, -1, 1))
+ GEM_BUG_ON(!refcount_read(&ref->count));
+ if (refcount_dec_not_one(&ref->count))
return;

__active_retire(ref);
@@ -189,8 +189,8 @@ active_work(struct work_struct *wrk)
static void
active_retire(struct i915_active *ref)
{
- GEM_BUG_ON(!atomic_read(&ref->count));
- if (atomic_add_unless(&ref->count, -1, 1))
+ GEM_BUG_ON(!refcount_read(&ref->count));
+ if (refcount_dec_not_one(&ref->count))
return;

if (ref->flags & I915_ACTIVE_RETIRE_SLEEPS) {
@@ -354,7 +354,7 @@ void __i915_active_init(struct i915_active *ref,
ref->cache = NULL;

init_llist_head(&ref->preallocated_barriers);
- atomic_set(&ref->count, 0);
+ refcount_set(&ref->count, 0);
__mutex_init(&ref->mutex, "i915_active", mkey);
__i915_active_fence_init(&ref->excl, NULL, excl_retire);
INIT_WORK(&ref->work, active_work);
@@ -445,7 +445,7 @@ int i915_active_add_request(struct i915_active *ref, struct i915_request *rq)

if (replace_barrier(ref, active)) {
RCU_INIT_POINTER(active->fence, NULL);
- atomic_dec(&ref->count);
+ refcount_dec(&ref->count);
}
if (!__i915_active_fence_set(active, fence))
__i915_active_acquire(ref);
@@ -488,14 +488,16 @@ i915_active_set_exclusive(struct i915_active *ref, struct dma_fence *f)
bool i915_active_acquire_if_busy(struct i915_active *ref)
{
debug_active_assert(ref);
- return atomic_add_unless(&ref->count, 1, 0);
+ return refcount_add_not_zero(1, &ref->count);
}

static void __i915_active_activate(struct i915_active *ref)
{
spin_lock_irq(&ref->tree_lock); /* __active_retire() */
- if (!atomic_fetch_inc(&ref->count))
+ if (!refcount_inc_not_zero(&ref->count)) {
+ refcount_inc(&ref->count);
debug_active_activate(ref);
+ }
spin_unlock_irq(&ref->tree_lock);
}

@@ -757,7 +759,7 @@ int i915_sw_fence_await_active(struct i915_sw_fence *fence,
void i915_active_fini(struct i915_active *ref)
{
debug_active_fini(ref);
- GEM_BUG_ON(atomic_read(&ref->count));
+ GEM_BUG_ON(refcount_read(&ref->count));
GEM_BUG_ON(work_pending(&ref->work));
mutex_destroy(&ref->mutex);

@@ -927,7 +929,7 @@ int i915_active_acquire_preallocate_barrier(struct i915_active *ref,

first = first->next;

- atomic_dec(&ref->count);
+ refcount_dec(&ref->count);
intel_engine_pm_put(barrier_to_engine(node));

kmem_cache_free(slab_cache, node);
diff --git a/drivers/gpu/drm/i915/i915_active.h b/drivers/gpu/drm/i915/i915_active.h
index 7eb44132183a..116c7c28466a 100644
--- a/drivers/gpu/drm/i915/i915_active.h
+++ b/drivers/gpu/drm/i915/i915_active.h
@@ -193,14 +193,14 @@ void i915_active_release(struct i915_active *ref);

static inline void __i915_active_acquire(struct i915_active *ref)
{
- GEM_BUG_ON(!atomic_read(&ref->count));
- atomic_inc(&ref->count);
+ GEM_BUG_ON(!refcount_read(&ref->count));
+ refcount_inc(&ref->count);
}

static inline bool
i915_active_is_idle(const struct i915_active *ref)
{
- return !atomic_read(&ref->count);
+ return !refcount_read(&ref->count);
}

void i915_active_fini(struct i915_active *ref);
diff --git a/drivers/gpu/drm/i915/i915_active_types.h b/drivers/gpu/drm/i915/i915_active_types.h
index b02a78ac87db..152a3a25d9f7 100644
--- a/drivers/gpu/drm/i915/i915_active_types.h
+++ b/drivers/gpu/drm/i915/i915_active_types.h
@@ -7,7 +7,7 @@
#ifndef _I915_ACTIVE_TYPES_H_
#define _I915_ACTIVE_TYPES_H_

-#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <linux/dma-fence.h>
#include <linux/llist.h>
#include <linux/mutex.h>
@@ -23,7 +23,7 @@ struct i915_active_fence {
struct active_node;

struct i915_active {
- atomic_t count;
+ refcount_t count;
struct mutex mutex;

spinlock_t tree_lock;
--
2.34.1




2022-12-25 02:17:13

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] drm/i915: convert i915_active.count from atomic_t to refcount_t

Hi Deepak,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on drm-intel/for-linux-next-fixes linus/master v6.1 next-20221220]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Deepak-R-Varma/drm-i915-convert-i915_active-count-from-atomic_t-to-refcount_t/20221225-055105
base: git://anongit.freedesktop.org/drm-intel for-linux-next
patch link: https://lore.kernel.org/r/Y6d0EDmyqJILVoRw%40qemulion
patch subject: [PATCH] drm/i915: convert i915_active.count from atomic_t to refcount_t
config: x86_64-allyesconfig
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/04a191f9a3d0f02bbd37735a47401bc92d685234
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Deepak-R-Varma/drm-i915-convert-i915_active-count-from-atomic_t-to-refcount_t/20221225-055105
git checkout 04a191f9a3d0f02bbd37735a47401bc92d685234
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 olddefconfig
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from drivers/gpu/drm/i915/i915_active.c:1152:
drivers/gpu/drm/i915/selftests/i915_active.c: In function '__live_active_setup':
>> drivers/gpu/drm/i915/selftests/i915_active.c:128:25: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types]
128 | if (atomic_read(&active->base.count) != count) {
| ^~~~~~~~~~~~~~~~~~~
| |
| refcount_t * {aka struct refcount_struct *}
In file included from include/linux/atomic.h:82,
from include/linux/cpumask.h:13,
from arch/x86/include/asm/cpumask.h:5,
from arch/x86/include/asm/msr.h:11,
from arch/x86/include/asm/processor.h:22,
from arch/x86/include/asm/cpufeature.h:5,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
include/linux/atomic/atomic-instrumented.h:25:29: note: expected 'const atomic_t *' but argument is of type 'refcount_t *' {aka 'struct refcount_struct *'}
25 | atomic_read(const atomic_t *v)
| ~~~~~~~~~~~~~~~~^
In file included from include/linux/kernel.h:29,
from arch/x86/include/asm/percpu.h:27,
from arch/x86/include/asm/preempt.h:6,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
drivers/gpu/drm/i915/selftests/i915_active.c:130:36: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types]
130 | atomic_read(&active->base.count), count);
| ^~~~~~~~~~~~~~~~~~~
| |
| refcount_t * {aka struct refcount_struct *}
include/linux/printk.h:429:33: note: in definition of macro 'printk_index_wrap'
429 | _p_func(_fmt, ##__VA_ARGS__); \
| ^~~~~~~~~~~
include/linux/printk.h:500:9: note: in expansion of macro 'printk'
500 | printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~
drivers/gpu/drm/i915/selftests/i915_active.c:129:17: note: in expansion of macro 'pr_err'
129 | pr_err("i915_active not tracking all requests, found %d, expected %d\n",
| ^~~~~~
In file included from include/linux/atomic.h:82,
from include/linux/cpumask.h:13,
from arch/x86/include/asm/cpumask.h:5,
from arch/x86/include/asm/msr.h:11,
from arch/x86/include/asm/processor.h:22,
from arch/x86/include/asm/cpufeature.h:5,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
include/linux/atomic/atomic-instrumented.h:25:29: note: expected 'const atomic_t *' but argument is of type 'refcount_t *' {aka 'struct refcount_struct *'}
25 | atomic_read(const atomic_t *v)
| ~~~~~~~~~~~~~~~~^
In file included from drivers/gpu/drm/i915/i915_active.c:1152:
drivers/gpu/drm/i915/selftests/i915_active.c: In function 'i915_active_print':
drivers/gpu/drm/i915/selftests/i915_active.c:282:52: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types]
282 | drm_printf(m, "\tcount: %d\n", atomic_read(&ref->count));
| ^~~~~~~~~~~
| |
| refcount_t * {aka struct refcount_struct *}
In file included from include/linux/atomic.h:82,
from include/linux/cpumask.h:13,
from arch/x86/include/asm/cpumask.h:5,
from arch/x86/include/asm/msr.h:11,
from arch/x86/include/asm/processor.h:22,
from arch/x86/include/asm/cpufeature.h:5,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
include/linux/atomic/atomic-instrumented.h:25:29: note: expected 'const atomic_t *' but argument is of type 'refcount_t *' {aka 'struct refcount_struct *'}
25 | atomic_read(const atomic_t *v)
| ~~~~~~~~~~~~~~~~^
In file included from drivers/gpu/drm/i915/i915_active.c:1152:
drivers/gpu/drm/i915/selftests/i915_active.c: In function 'active_flush':
>> drivers/gpu/drm/i915/selftests/i915_active.c:327:20: error: passing argument 1 of 'atomic_dec' from incompatible pointer type [-Werror=incompatible-pointer-types]
327 | atomic_dec(&ref->count);
| ^~~~~~~~~~~
| |
| refcount_t * {aka struct refcount_struct *}
In file included from include/linux/atomic.h:82,
from include/linux/cpumask.h:13,
from arch/x86/include/asm/cpumask.h:5,
from arch/x86/include/asm/msr.h:11,
from arch/x86/include/asm/processor.h:22,
from arch/x86/include/asm/cpufeature.h:5,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
include/linux/atomic/atomic-instrumented.h:255:22: note: expected 'atomic_t *' but argument is of type 'refcount_t *' {aka 'struct refcount_struct *'}
255 | atomic_dec(atomic_t *v)
| ~~~~~~~~~~^
cc1: all warnings being treated as errors


vim +/atomic_read +128 drivers/gpu/drm/i915/selftests/i915_active.c

5361db1a33c7e2 Chris Wilson 2019-06-21 76
5361db1a33c7e2 Chris Wilson 2019-06-21 77 static struct live_active *
5361db1a33c7e2 Chris Wilson 2019-06-21 78 __live_active_setup(struct drm_i915_private *i915)
64d6c500a38434 Chris Wilson 2019-02-05 79 {
64d6c500a38434 Chris Wilson 2019-02-05 80 struct intel_engine_cs *engine;
64d6c500a38434 Chris Wilson 2019-02-05 81 struct i915_sw_fence *submit;
5361db1a33c7e2 Chris Wilson 2019-06-21 82 struct live_active *active;
64d6c500a38434 Chris Wilson 2019-02-05 83 unsigned int count = 0;
64d6c500a38434 Chris Wilson 2019-02-05 84 int err = 0;
64d6c500a38434 Chris Wilson 2019-02-05 85
5361db1a33c7e2 Chris Wilson 2019-06-21 86 active = __live_alloc(i915);
5361db1a33c7e2 Chris Wilson 2019-06-21 87 if (!active)
5361db1a33c7e2 Chris Wilson 2019-06-21 88 return ERR_PTR(-ENOMEM);
64d6c500a38434 Chris Wilson 2019-02-05 89
5361db1a33c7e2 Chris Wilson 2019-06-21 90 submit = heap_fence_create(GFP_KERNEL);
5361db1a33c7e2 Chris Wilson 2019-06-21 91 if (!submit) {
5361db1a33c7e2 Chris Wilson 2019-06-21 92 kfree(active);
5361db1a33c7e2 Chris Wilson 2019-06-21 93 return ERR_PTR(-ENOMEM);
5361db1a33c7e2 Chris Wilson 2019-06-21 94 }
64d6c500a38434 Chris Wilson 2019-02-05 95
12c255b5dad115 Chris Wilson 2019-06-21 96 err = i915_active_acquire(&active->base);
12c255b5dad115 Chris Wilson 2019-06-21 97 if (err)
64d6c500a38434 Chris Wilson 2019-02-05 98 goto out;
64d6c500a38434 Chris Wilson 2019-02-05 99
928da10c0ca2ae Chris Wilson 2019-10-21 100 for_each_uabi_engine(engine, i915) {
64d6c500a38434 Chris Wilson 2019-02-05 101 struct i915_request *rq;
64d6c500a38434 Chris Wilson 2019-02-05 102
de5825beae9a0a Chris Wilson 2019-11-25 103 rq = intel_engine_create_kernel_request(engine);
64d6c500a38434 Chris Wilson 2019-02-05 104 if (IS_ERR(rq)) {
64d6c500a38434 Chris Wilson 2019-02-05 105 err = PTR_ERR(rq);
64d6c500a38434 Chris Wilson 2019-02-05 106 break;
64d6c500a38434 Chris Wilson 2019-02-05 107 }
64d6c500a38434 Chris Wilson 2019-02-05 108
64d6c500a38434 Chris Wilson 2019-02-05 109 err = i915_sw_fence_await_sw_fence_gfp(&rq->submit,
64d6c500a38434 Chris Wilson 2019-02-05 110 submit,
64d6c500a38434 Chris Wilson 2019-02-05 111 GFP_KERNEL);
64d6c500a38434 Chris Wilson 2019-02-05 112 if (err >= 0)
d19d71fc2b15bf Chris Wilson 2019-09-19 113 err = i915_active_add_request(&active->base, rq);
64d6c500a38434 Chris Wilson 2019-02-05 114 i915_request_add(rq);
64d6c500a38434 Chris Wilson 2019-02-05 115 if (err) {
64d6c500a38434 Chris Wilson 2019-02-05 116 pr_err("Failed to track active ref!\n");
64d6c500a38434 Chris Wilson 2019-02-05 117 break;
64d6c500a38434 Chris Wilson 2019-02-05 118 }
64d6c500a38434 Chris Wilson 2019-02-05 119
64d6c500a38434 Chris Wilson 2019-02-05 120 count++;
64d6c500a38434 Chris Wilson 2019-02-05 121 }
64d6c500a38434 Chris Wilson 2019-02-05 122
64d6c500a38434 Chris Wilson 2019-02-05 123 i915_active_release(&active->base);
274cbf20fd108f Chris Wilson 2019-10-04 124 if (READ_ONCE(active->retired) && count) {
64d6c500a38434 Chris Wilson 2019-02-05 125 pr_err("i915_active retired before submission!\n");
64d6c500a38434 Chris Wilson 2019-02-05 126 err = -EINVAL;
64d6c500a38434 Chris Wilson 2019-02-05 127 }
12c255b5dad115 Chris Wilson 2019-06-21 @128 if (atomic_read(&active->base.count) != count) {
64d6c500a38434 Chris Wilson 2019-02-05 129 pr_err("i915_active not tracking all requests, found %d, expected %d\n",
12c255b5dad115 Chris Wilson 2019-06-21 130 atomic_read(&active->base.count), count);
64d6c500a38434 Chris Wilson 2019-02-05 131 err = -EINVAL;
64d6c500a38434 Chris Wilson 2019-02-05 132 }
64d6c500a38434 Chris Wilson 2019-02-05 133
64d6c500a38434 Chris Wilson 2019-02-05 134 out:
64d6c500a38434 Chris Wilson 2019-02-05 135 i915_sw_fence_commit(submit);
64d6c500a38434 Chris Wilson 2019-02-05 136 heap_fence_put(submit);
12c255b5dad115 Chris Wilson 2019-06-21 137 if (err) {
12c255b5dad115 Chris Wilson 2019-06-21 138 __live_put(active);
12c255b5dad115 Chris Wilson 2019-06-21 139 active = ERR_PTR(err);
12c255b5dad115 Chris Wilson 2019-06-21 140 }
64d6c500a38434 Chris Wilson 2019-02-05 141
12c255b5dad115 Chris Wilson 2019-06-21 142 return active;
64d6c500a38434 Chris Wilson 2019-02-05 143 }
64d6c500a38434 Chris Wilson 2019-02-05 144
64d6c500a38434 Chris Wilson 2019-02-05 145 static int live_active_wait(void *arg)
64d6c500a38434 Chris Wilson 2019-02-05 146 {
64d6c500a38434 Chris Wilson 2019-02-05 147 struct drm_i915_private *i915 = arg;
5361db1a33c7e2 Chris Wilson 2019-06-21 148 struct live_active *active;
5361db1a33c7e2 Chris Wilson 2019-06-21 149 int err = 0;
64d6c500a38434 Chris Wilson 2019-02-05 150
64d6c500a38434 Chris Wilson 2019-02-05 151 /* Check that we get a callback when requests retire upon waiting */
64d6c500a38434 Chris Wilson 2019-02-05 152
5361db1a33c7e2 Chris Wilson 2019-06-21 153 active = __live_active_setup(i915);
b1e3177bd1d8f4 Chris Wilson 2019-10-04 154 if (IS_ERR(active))
b1e3177bd1d8f4 Chris Wilson 2019-10-04 155 return PTR_ERR(active);
64d6c500a38434 Chris Wilson 2019-02-05 156
d75a92a8146793 Chris Wilson 2020-03-27 157 __i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
274cbf20fd108f Chris Wilson 2019-10-04 158 if (!READ_ONCE(active->retired)) {
5de34ed13787c4 Chris Wilson 2019-12-10 159 struct drm_printer p = drm_err_printer(__func__);
5de34ed13787c4 Chris Wilson 2019-12-10 160
64d6c500a38434 Chris Wilson 2019-02-05 161 pr_err("i915_active not retired after waiting!\n");
5de34ed13787c4 Chris Wilson 2019-12-10 162 i915_active_print(&active->base, &p);
5de34ed13787c4 Chris Wilson 2019-12-10 163
64d6c500a38434 Chris Wilson 2019-02-05 164 err = -EINVAL;
64d6c500a38434 Chris Wilson 2019-02-05 165 }
64d6c500a38434 Chris Wilson 2019-02-05 166
12c255b5dad115 Chris Wilson 2019-06-21 167 __live_put(active);
5361db1a33c7e2 Chris Wilson 2019-06-21 168
7e8057626640cf Chris Wilson 2019-10-04 169 if (igt_flush_test(i915))
64d6c500a38434 Chris Wilson 2019-02-05 170 err = -EIO;
5361db1a33c7e2 Chris Wilson 2019-06-21 171
64d6c500a38434 Chris Wilson 2019-02-05 172 return err;
64d6c500a38434 Chris Wilson 2019-02-05 173 }
64d6c500a38434 Chris Wilson 2019-02-05 174
64d6c500a38434 Chris Wilson 2019-02-05 175 static int live_active_retire(void *arg)
64d6c500a38434 Chris Wilson 2019-02-05 176 {
64d6c500a38434 Chris Wilson 2019-02-05 177 struct drm_i915_private *i915 = arg;
5361db1a33c7e2 Chris Wilson 2019-06-21 178 struct live_active *active;
5361db1a33c7e2 Chris Wilson 2019-06-21 179 int err = 0;
64d6c500a38434 Chris Wilson 2019-02-05 180
64d6c500a38434 Chris Wilson 2019-02-05 181 /* Check that we get a callback when requests are indirectly retired */
64d6c500a38434 Chris Wilson 2019-02-05 182
5361db1a33c7e2 Chris Wilson 2019-06-21 183 active = __live_active_setup(i915);
b1e3177bd1d8f4 Chris Wilson 2019-10-04 184 if (IS_ERR(active))
b1e3177bd1d8f4 Chris Wilson 2019-10-04 185 return PTR_ERR(active);
64d6c500a38434 Chris Wilson 2019-02-05 186
64d6c500a38434 Chris Wilson 2019-02-05 187 /* waits for & retires all requests */
7e8057626640cf Chris Wilson 2019-10-04 188 if (igt_flush_test(i915))
64d6c500a38434 Chris Wilson 2019-02-05 189 err = -EIO;
64d6c500a38434 Chris Wilson 2019-02-05 190
274cbf20fd108f Chris Wilson 2019-10-04 191 if (!READ_ONCE(active->retired)) {
5de34ed13787c4 Chris Wilson 2019-12-10 192 struct drm_printer p = drm_err_printer(__func__);
5de34ed13787c4 Chris Wilson 2019-12-10 193
64d6c500a38434 Chris Wilson 2019-02-05 194 pr_err("i915_active not retired after flushing!\n");
5de34ed13787c4 Chris Wilson 2019-12-10 195 i915_active_print(&active->base, &p);
5de34ed13787c4 Chris Wilson 2019-12-10 196
64d6c500a38434 Chris Wilson 2019-02-05 197 err = -EINVAL;
64d6c500a38434 Chris Wilson 2019-02-05 198 }
64d6c500a38434 Chris Wilson 2019-02-05 199
12c255b5dad115 Chris Wilson 2019-06-21 200 __live_put(active);
5361db1a33c7e2 Chris Wilson 2019-06-21 201
64d6c500a38434 Chris Wilson 2019-02-05 202 return err;
64d6c500a38434 Chris Wilson 2019-02-05 203 }
64d6c500a38434 Chris Wilson 2019-02-05 204
d13a31770077a8 Chris Wilson 2020-02-25 205 static int live_active_barrier(void *arg)
d13a31770077a8 Chris Wilson 2020-02-25 206 {
d13a31770077a8 Chris Wilson 2020-02-25 207 struct drm_i915_private *i915 = arg;
d13a31770077a8 Chris Wilson 2020-02-25 208 struct intel_engine_cs *engine;
d13a31770077a8 Chris Wilson 2020-02-25 209 struct live_active *active;
d13a31770077a8 Chris Wilson 2020-02-25 210 int err = 0;
d13a31770077a8 Chris Wilson 2020-02-25 211
d13a31770077a8 Chris Wilson 2020-02-25 212 /* Check that we get a callback when requests retire upon waiting */
d13a31770077a8 Chris Wilson 2020-02-25 213
d13a31770077a8 Chris Wilson 2020-02-25 214 active = __live_alloc(i915);
d13a31770077a8 Chris Wilson 2020-02-25 215 if (!active)
d13a31770077a8 Chris Wilson 2020-02-25 216 return -ENOMEM;
d13a31770077a8 Chris Wilson 2020-02-25 217
d13a31770077a8 Chris Wilson 2020-02-25 218 err = i915_active_acquire(&active->base);
d13a31770077a8 Chris Wilson 2020-02-25 219 if (err)
d13a31770077a8 Chris Wilson 2020-02-25 220 goto out;
d13a31770077a8 Chris Wilson 2020-02-25 221
d13a31770077a8 Chris Wilson 2020-02-25 222 for_each_uabi_engine(engine, i915) {
d13a31770077a8 Chris Wilson 2020-02-25 223 err = i915_active_acquire_preallocate_barrier(&active->base,
d13a31770077a8 Chris Wilson 2020-02-25 224 engine);
d13a31770077a8 Chris Wilson 2020-02-25 225 if (err)
d13a31770077a8 Chris Wilson 2020-02-25 226 break;
d13a31770077a8 Chris Wilson 2020-02-25 227
d13a31770077a8 Chris Wilson 2020-02-25 228 i915_active_acquire_barrier(&active->base);
d13a31770077a8 Chris Wilson 2020-02-25 229 }
d13a31770077a8 Chris Wilson 2020-02-25 230
d13a31770077a8 Chris Wilson 2020-02-25 231 i915_active_release(&active->base);
d75a92a8146793 Chris Wilson 2020-03-27 232 if (err)
d75a92a8146793 Chris Wilson 2020-03-27 233 goto out;
d13a31770077a8 Chris Wilson 2020-02-25 234
d75a92a8146793 Chris Wilson 2020-03-27 235 __i915_active_wait(&active->base, TASK_UNINTERRUPTIBLE);
d75a92a8146793 Chris Wilson 2020-03-27 236 if (!READ_ONCE(active->retired)) {
d13a31770077a8 Chris Wilson 2020-02-25 237 pr_err("i915_active not retired after flushing barriers!\n");
d13a31770077a8 Chris Wilson 2020-02-25 238 err = -EINVAL;
d13a31770077a8 Chris Wilson 2020-02-25 239 }
d13a31770077a8 Chris Wilson 2020-02-25 240
d13a31770077a8 Chris Wilson 2020-02-25 241 out:
d13a31770077a8 Chris Wilson 2020-02-25 242 __live_put(active);
d13a31770077a8 Chris Wilson 2020-02-25 243
d13a31770077a8 Chris Wilson 2020-02-25 244 if (igt_flush_test(i915))
d13a31770077a8 Chris Wilson 2020-02-25 245 err = -EIO;
d13a31770077a8 Chris Wilson 2020-02-25 246
d13a31770077a8 Chris Wilson 2020-02-25 247 return err;
d13a31770077a8 Chris Wilson 2020-02-25 248 }
d13a31770077a8 Chris Wilson 2020-02-25 249
64d6c500a38434 Chris Wilson 2019-02-05 250 int i915_active_live_selftests(struct drm_i915_private *i915)
64d6c500a38434 Chris Wilson 2019-02-05 251 {
64d6c500a38434 Chris Wilson 2019-02-05 252 static const struct i915_subtest tests[] = {
64d6c500a38434 Chris Wilson 2019-02-05 253 SUBTEST(live_active_wait),
64d6c500a38434 Chris Wilson 2019-02-05 254 SUBTEST(live_active_retire),
d13a31770077a8 Chris Wilson 2020-02-25 255 SUBTEST(live_active_barrier),
64d6c500a38434 Chris Wilson 2019-02-05 256 };
64d6c500a38434 Chris Wilson 2019-02-05 257
8c2699fad60e3f Andi Shyti 2021-12-14 258 if (intel_gt_is_wedged(to_gt(i915)))
64d6c500a38434 Chris Wilson 2019-02-05 259 return 0;
64d6c500a38434 Chris Wilson 2019-02-05 260
64d6c500a38434 Chris Wilson 2019-02-05 261 return i915_subtests(tests, i915);
64d6c500a38434 Chris Wilson 2019-02-05 262 }
164a4128869ffc Chris Wilson 2019-10-31 263
164a4128869ffc Chris Wilson 2019-10-31 264 static struct intel_engine_cs *node_to_barrier(struct active_node *it)
164a4128869ffc Chris Wilson 2019-10-31 265 {
164a4128869ffc Chris Wilson 2019-10-31 266 struct intel_engine_cs *engine;
164a4128869ffc Chris Wilson 2019-10-31 267
164a4128869ffc Chris Wilson 2019-10-31 268 if (!is_barrier(&it->base))
164a4128869ffc Chris Wilson 2019-10-31 269 return NULL;
164a4128869ffc Chris Wilson 2019-10-31 270
164a4128869ffc Chris Wilson 2019-10-31 271 engine = __barrier_to_engine(it);
164a4128869ffc Chris Wilson 2019-10-31 272 smp_rmb(); /* serialise with add_active_barriers */
164a4128869ffc Chris Wilson 2019-10-31 273 if (!is_barrier(&it->base))
164a4128869ffc Chris Wilson 2019-10-31 274 return NULL;
164a4128869ffc Chris Wilson 2019-10-31 275
164a4128869ffc Chris Wilson 2019-10-31 276 return engine;
164a4128869ffc Chris Wilson 2019-10-31 277 }
164a4128869ffc Chris Wilson 2019-10-31 278
164a4128869ffc Chris Wilson 2019-10-31 279 void i915_active_print(struct i915_active *ref, struct drm_printer *m)
164a4128869ffc Chris Wilson 2019-10-31 280 {
2386b492ded48b Chris Wilson 2020-03-19 281 drm_printf(m, "active %ps:%ps\n", ref->active, ref->retire);
164a4128869ffc Chris Wilson 2019-10-31 282 drm_printf(m, "\tcount: %d\n", atomic_read(&ref->count));
164a4128869ffc Chris Wilson 2019-10-31 283 drm_printf(m, "\tpreallocated barriers? %s\n",
01fabda8e3d62e Lucas De Marchi 2022-02-25 284 str_yes_no(!llist_empty(&ref->preallocated_barriers)));
164a4128869ffc Chris Wilson 2019-10-31 285
164a4128869ffc Chris Wilson 2019-10-31 286 if (i915_active_acquire_if_busy(ref)) {
164a4128869ffc Chris Wilson 2019-10-31 287 struct active_node *it, *n;
164a4128869ffc Chris Wilson 2019-10-31 288
164a4128869ffc Chris Wilson 2019-10-31 289 rbtree_postorder_for_each_entry_safe(it, n, &ref->tree, node) {
164a4128869ffc Chris Wilson 2019-10-31 290 struct intel_engine_cs *engine;
164a4128869ffc Chris Wilson 2019-10-31 291
164a4128869ffc Chris Wilson 2019-10-31 292 engine = node_to_barrier(it);
164a4128869ffc Chris Wilson 2019-10-31 293 if (engine) {
164a4128869ffc Chris Wilson 2019-10-31 294 drm_printf(m, "\tbarrier: %s\n", engine->name);
164a4128869ffc Chris Wilson 2019-10-31 295 continue;
164a4128869ffc Chris Wilson 2019-10-31 296 }
164a4128869ffc Chris Wilson 2019-10-31 297
164a4128869ffc Chris Wilson 2019-10-31 298 if (i915_active_fence_isset(&it->base)) {
164a4128869ffc Chris Wilson 2019-10-31 299 drm_printf(m,
164a4128869ffc Chris Wilson 2019-10-31 300 "\ttimeline: %llx\n", it->timeline);
164a4128869ffc Chris Wilson 2019-10-31 301 continue;
164a4128869ffc Chris Wilson 2019-10-31 302 }
164a4128869ffc Chris Wilson 2019-10-31 303 }
164a4128869ffc Chris Wilson 2019-10-31 304
164a4128869ffc Chris Wilson 2019-10-31 305 i915_active_release(ref);
164a4128869ffc Chris Wilson 2019-10-31 306 }
164a4128869ffc Chris Wilson 2019-10-31 307 }
38813767c7c5d9 Chris Wilson 2019-11-01 308
38813767c7c5d9 Chris Wilson 2019-11-01 309 static void spin_unlock_wait(spinlock_t *lock)
38813767c7c5d9 Chris Wilson 2019-11-01 310 {
38813767c7c5d9 Chris Wilson 2019-11-01 311 spin_lock_irq(lock);
38813767c7c5d9 Chris Wilson 2019-11-01 312 spin_unlock_irq(lock);
38813767c7c5d9 Chris Wilson 2019-11-01 313 }
38813767c7c5d9 Chris Wilson 2019-11-01 314
e3e7aeec3281af Chris Wilson 2020-03-06 315 static void active_flush(struct i915_active *ref,
e3e7aeec3281af Chris Wilson 2020-03-06 316 struct i915_active_fence *active)
e3e7aeec3281af Chris Wilson 2020-03-06 317 {
e3e7aeec3281af Chris Wilson 2020-03-06 318 struct dma_fence *fence;
e3e7aeec3281af Chris Wilson 2020-03-06 319
e3e7aeec3281af Chris Wilson 2020-03-06 320 fence = xchg(__active_fence_slot(active), NULL);
e3e7aeec3281af Chris Wilson 2020-03-06 321 if (!fence)
e3e7aeec3281af Chris Wilson 2020-03-06 322 return;
e3e7aeec3281af Chris Wilson 2020-03-06 323
e3e7aeec3281af Chris Wilson 2020-03-06 324 spin_lock_irq(fence->lock);
e3e7aeec3281af Chris Wilson 2020-03-06 325 __list_del_entry(&active->cb.node);
e3e7aeec3281af Chris Wilson 2020-03-06 326 spin_unlock_irq(fence->lock); /* serialise with fence->cb_list */
e3e7aeec3281af Chris Wilson 2020-03-06 @327 atomic_dec(&ref->count);
e3e7aeec3281af Chris Wilson 2020-03-06 328
e3e7aeec3281af Chris Wilson 2020-03-06 329 GEM_BUG_ON(!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags));
e3e7aeec3281af Chris Wilson 2020-03-06 330 }
e3e7aeec3281af Chris Wilson 2020-03-06 331

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (26.34 kB)
config (297.78 kB)
Download all attachments

2022-12-25 04:07:06

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] drm/i915: convert i915_active.count from atomic_t to refcount_t

Hi Deepak,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on drm-intel/for-linux-next-fixes linus/master v6.1 next-20221220]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Deepak-R-Varma/drm-i915-convert-i915_active-count-from-atomic_t-to-refcount_t/20221225-055105
base: git://anongit.freedesktop.org/drm-intel for-linux-next
patch link: https://lore.kernel.org/r/Y6d0EDmyqJILVoRw%40qemulion
patch subject: [PATCH] drm/i915: convert i915_active.count from atomic_t to refcount_t
config: x86_64-randconfig-c002
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/04a191f9a3d0f02bbd37735a47401bc92d685234
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Deepak-R-Varma/drm-i915-convert-i915_active-count-from-atomic_t-to-refcount_t/20221225-055105
git checkout 04a191f9a3d0f02bbd37735a47401bc92d685234
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 olddefconfig
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/gpu/drm/i915/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

drivers/gpu/drm/i915/i915_active.c: In function 'debug_active_activate':
>> drivers/gpu/drm/i915/i915_active.c:95:26: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types]
95 | if (!atomic_read(&ref->count)) /* before the first inc */
| ^~~~~~~~~~~
| |
| refcount_t * {aka struct refcount_struct *}
In file included from include/linux/atomic.h:82,
from include/linux/jump_label.h:254,
from include/linux/static_key.h:1,
from arch/x86/include/asm/nospec-branch.h:6,
from arch/x86/include/asm/paravirt_types.h:40,
from arch/x86/include/asm/ptrace.h:97,
from arch/x86/include/asm/math_emu.h:5,
from arch/x86/include/asm/processor.h:13,
from arch/x86/include/asm/cpufeature.h:5,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
include/linux/atomic/atomic-instrumented.h:25:29: note: expected 'const atomic_t *' but argument is of type 'refcount_t *' {aka 'struct refcount_struct *'}
25 | atomic_read(const atomic_t *v)
| ~~~~~~~~~~~~~~~~^
drivers/gpu/drm/i915/i915_active.c: In function 'debug_active_deactivate':
drivers/gpu/drm/i915/i915_active.c:102:26: error: passing argument 1 of 'atomic_read' from incompatible pointer type [-Werror=incompatible-pointer-types]
102 | if (!atomic_read(&ref->count)) /* after the last dec */
| ^~~~~~~~~~~
| |
| refcount_t * {aka struct refcount_struct *}
In file included from include/linux/atomic.h:82,
from include/linux/jump_label.h:254,
from include/linux/static_key.h:1,
from arch/x86/include/asm/nospec-branch.h:6,
from arch/x86/include/asm/paravirt_types.h:40,
from arch/x86/include/asm/ptrace.h:97,
from arch/x86/include/asm/math_emu.h:5,
from arch/x86/include/asm/processor.h:13,
from arch/x86/include/asm/cpufeature.h:5,
from arch/x86/include/asm/thread_info.h:53,
from include/linux/thread_info.h:60,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:56,
from include/linux/debugobjects.h:6,
from drivers/gpu/drm/i915/i915_active.c:7:
include/linux/atomic/atomic-instrumented.h:25:29: note: expected 'const atomic_t *' but argument is of type 'refcount_t *' {aka 'struct refcount_struct *'}
25 | atomic_read(const atomic_t *v)
| ~~~~~~~~~~~~~~~~^
cc1: all warnings being treated as errors


vim +/atomic_read +95 drivers/gpu/drm/i915/i915_active.c

5361db1a33c7e2 Chris Wilson 2019-06-21 91
5361db1a33c7e2 Chris Wilson 2019-06-21 92 static void debug_active_activate(struct i915_active *ref)
5361db1a33c7e2 Chris Wilson 2019-06-21 93 {
bbca083de291a0 Chris Wilson 2019-12-05 94 lockdep_assert_held(&ref->tree_lock);
f52c6d0df6909a Chris Wilson 2019-08-27 @95 if (!atomic_read(&ref->count)) /* before the first inc */
5361db1a33c7e2 Chris Wilson 2019-06-21 96 debug_object_activate(ref, &active_debug_desc);
5361db1a33c7e2 Chris Wilson 2019-06-21 97 }
5361db1a33c7e2 Chris Wilson 2019-06-21 98

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (5.64 kB)
config (127.08 kB)
Download all attachments