linux_dsm_epyc7002/drivers/gpu/drm/i915/i915_sw_fence.h
Chris Wilson 556b748710 drm/i915: Give each sw_fence its own lockclass
Localise the static struct lock_class_key to the caller of
i915_sw_fence_init() so that we create a lock_class instance for each
unique sw_fence rather than all sw_fences sharing the same
lock_class. This eliminate some lockdep false positive when using fences
from within fence callbacks.

For the relatively small number of fences currently in use [2], this adds
160 bytes of unused text/code when lockdep is disabled. This seems
quite high, but fully reducing it via ifdeffery is also quite ugly.
Removing the #fence strings saves 72 bytes with just a single #ifdef.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20161114204105.29171-1-chris@chris-wilson.co.uk
2016-11-14 21:00:20 +00:00

89 lines
2.3 KiB
C

/*
* i915_sw_fence.h - library routines for N:M synchronisation points
*
* Copyright (C) 2016 Intel Corporation
*
* This file is released under the GPLv2.
*
*/
#ifndef _I915_SW_FENCE_H_
#define _I915_SW_FENCE_H_
#include <linux/gfp.h>
#include <linux/kref.h>
#include <linux/notifier.h> /* for NOTIFY_DONE */
#include <linux/wait.h>
struct completion;
struct dma_fence;
struct dma_fence_ops;
struct reservation_object;
struct i915_sw_fence {
wait_queue_head_t wait;
unsigned long flags;
struct kref kref;
atomic_t pending;
};
#define I915_SW_FENCE_CHECKED_BIT 0 /* used internally for DAG checking */
#define I915_SW_FENCE_PRIVATE_BIT 1 /* available for use by owner */
#define I915_SW_FENCE_MASK (~3)
enum i915_sw_fence_notify {
FENCE_COMPLETE,
FENCE_FREE
};
typedef int (*i915_sw_fence_notify_t)(struct i915_sw_fence *,
enum i915_sw_fence_notify state);
#define __i915_sw_fence_call __aligned(4)
void __i915_sw_fence_init(struct i915_sw_fence *fence,
i915_sw_fence_notify_t fn,
const char *name,
struct lock_class_key *key);
#ifdef CONFIG_LOCKDEP
#define i915_sw_fence_init(fence, fn) \
do { \
static struct lock_class_key __key; \
\
__i915_sw_fence_init((fence), (fn), #fence, &__key); \
} while (0)
#else
#define i915_sw_fence_init(fence, fn) \
__i915_sw_fence_init((fence), (fn), NULL, NULL)
#endif
void i915_sw_fence_commit(struct i915_sw_fence *fence);
int i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence,
struct i915_sw_fence *after,
wait_queue_t *wq);
int i915_sw_fence_await_sw_fence_gfp(struct i915_sw_fence *fence,
struct i915_sw_fence *after,
gfp_t gfp);
int i915_sw_fence_await_dma_fence(struct i915_sw_fence *fence,
struct dma_fence *dma,
unsigned long timeout,
gfp_t gfp);
int i915_sw_fence_await_reservation(struct i915_sw_fence *fence,
struct reservation_object *resv,
const struct dma_fence_ops *exclude,
bool write,
unsigned long timeout,
gfp_t gfp);
static inline bool i915_sw_fence_done(const struct i915_sw_fence *fence)
{
return atomic_read(&fence->pending) < 0;
}
static inline void i915_sw_fence_wait(struct i915_sw_fence *fence)
{
wait_event(fence->wait, i915_sw_fence_done(fence));
}
#endif /* _I915_SW_FENCE_H_ */