drm-misc-next for $kernel-version:
UAPI Changes:
Cross-subsystem Changes:
- dma-buf: Avoid a warning with some allocations, Remove
DMA_FENCE_TRACE macros
Core Changes:
- bridge: New helper to git rid of panels in drivers
- fence: Improve dma_fence_add_callback documentation, Improve
dma_fence_ops->wait documentation
- ioctl: Unexport drm_ioctl_permit
- lease: Documentation improvements
- fourcc: Add new macro to determine the modifier vendor
- quirks: Add the Steam Deck, Chuwi HiBook, Chuwi Hi10 Pro, Samsung
Galaxy Book 10.6, KD Kurio Smart C15200 2-in-1, Lenovo Ideapad D330
- resv: Improve the documentation
- shmem-helpers: Allocate WC pages on x86, Switch to vmf_insert_pfn
- sched: Fix for a timer being canceled too soon, Avoid null pointer
derefence if the fence is null in drm_sched_fence_free, Convert
drivers to rely on its dependency tracking
- ttm: Switch to kerneldoc, new helper to clear all DMA mappings, pool
shrinker optitimization, Remove ttm_tt_destroy_common, Fix for
unbinding on multiple drivers
Driver Changes:
- bochs: New PCI IDs
- msm: Fence ordering impromevemnts
- stm: Add layer alpha support, zpos
- v3d: Fix for a Vulkan CTS failure
- vc4: Conversion to the new bridge helpers
- vgem: Use shmem helpers
- virtio: Support mapping exported vram
- zte: Remove obsolete driver
- bridge: Probe improvements for it66121, enable DSI EOTP for anx7625,
errors propagation improvements for anx7625
- panels: 60fps mode for otm8009a, New driver for Samsung S6D27A1
-----BEGIN PGP SIGNATURE-----
iHUEABYIAB0WIQRcEzekXsqa64kGDp7j7w1vZxhRxQUCYULyqgAKCRDj7w1vZxhR
xVR1AP96dB3rfB0uIEvujMROBqupaKbYvP/7qilfMGIwLotDqQD/RKNB+EAaoHtT
hRA7zmz7kwYA/l8PihmF1zoFddX21gA=
=nFnK
-----END PGP SIGNATURE-----
Merge tag 'drm-misc-next-2021-09-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for $kernel-version:
UAPI Changes:
Cross-subsystem Changes:
- dma-buf: Avoid a warning with some allocations, Remove
DMA_FENCE_TRACE macros
Core Changes:
- bridge: New helper to git rid of panels in drivers
- fence: Improve dma_fence_add_callback documentation, Improve
dma_fence_ops->wait documentation
- ioctl: Unexport drm_ioctl_permit
- lease: Documentation improvements
- fourcc: Add new macro to determine the modifier vendor
- quirks: Add the Steam Deck, Chuwi HiBook, Chuwi Hi10 Pro, Samsung
Galaxy Book 10.6, KD Kurio Smart C15200 2-in-1, Lenovo Ideapad D330
- resv: Improve the documentation
- shmem-helpers: Allocate WC pages on x86, Switch to vmf_insert_pfn
- sched: Fix for a timer being canceled too soon, Avoid null pointer
derefence if the fence is null in drm_sched_fence_free, Convert
drivers to rely on its dependency tracking
- ttm: Switch to kerneldoc, new helper to clear all DMA mappings, pool
shrinker optitimization, Remove ttm_tt_destroy_common, Fix for
unbinding on multiple drivers
Driver Changes:
- bochs: New PCI IDs
- msm: Fence ordering impromevemnts
- stm: Add layer alpha support, zpos
- v3d: Fix for a Vulkan CTS failure
- vc4: Conversion to the new bridge helpers
- vgem: Use shmem helpers
- virtio: Support mapping exported vram
- zte: Remove obsolete driver
- bridge: Probe improvements for it66121, enable DSI EOTP for anx7625,
errors propagation improvements for anx7625
- panels: 60fps mode for otm8009a, New driver for Samsung S6D27A1
Signed-off-by: Dave Airlie <airlied@redhat.com>
# gpg: Signature made Thu 16 Sep 2021 17:30:50 AEST
# gpg: using EDDSA key 5C1337A45ECA9AEB89060E9EE3EF0D6F671851C5
# gpg: Can't check signature: No public key
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210916073132.ptbbmjetm7v3ufq3@gilmour
This commit is contained in:
commit
0dfc70818a
145 changed files with 2080 additions and 5441 deletions
|
|
@ -420,6 +420,13 @@ struct dma_buf {
|
|||
* - Dynamic importers should set fences for any access that they can't
|
||||
* disable immediately from their &dma_buf_attach_ops.move_notify
|
||||
* callback.
|
||||
*
|
||||
* IMPORTANT:
|
||||
*
|
||||
* All drivers must obey the struct dma_resv rules, specifically the
|
||||
* rules for updating fences, see &dma_resv.fence_excl and
|
||||
* &dma_resv.fence. If these dependency rules are broken access tracking
|
||||
* can be lost resulting in use after free issues.
|
||||
*/
|
||||
struct dma_resv *resv;
|
||||
|
||||
|
|
|
|||
|
|
@ -214,19 +214,15 @@ struct dma_fence_ops {
|
|||
* Custom wait implementation, defaults to dma_fence_default_wait() if
|
||||
* not set.
|
||||
*
|
||||
* The dma_fence_default_wait implementation should work for any fence, as long
|
||||
* as @enable_signaling works correctly. This hook allows drivers to
|
||||
* have an optimized version for the case where a process context is
|
||||
* already available, e.g. if @enable_signaling for the general case
|
||||
* needs to set up a worker thread.
|
||||
* Deprecated and should not be used by new implementations. Only used
|
||||
* by existing implementations which need special handling for their
|
||||
* hardware reset procedure.
|
||||
*
|
||||
* Must return -ERESTARTSYS if the wait is intr = true and the wait was
|
||||
* interrupted, and remaining jiffies if fence has signaled, or 0 if wait
|
||||
* timed out. Can also return other error values on custom implementations,
|
||||
* which should be treated as if the fence is signaled. For example a hardware
|
||||
* lockup could be reported like that.
|
||||
*
|
||||
* This callback is optional.
|
||||
*/
|
||||
signed long (*wait)(struct dma_fence *fence,
|
||||
bool intr, signed long timeout);
|
||||
|
|
@ -590,26 +586,4 @@ struct dma_fence *dma_fence_get_stub(void);
|
|||
struct dma_fence *dma_fence_allocate_private_stub(void);
|
||||
u64 dma_fence_context_alloc(unsigned num);
|
||||
|
||||
#define DMA_FENCE_TRACE(f, fmt, args...) \
|
||||
do { \
|
||||
struct dma_fence *__ff = (f); \
|
||||
if (IS_ENABLED(CONFIG_DMA_FENCE_TRACE)) \
|
||||
pr_info("f %llu#%llu: " fmt, \
|
||||
__ff->context, __ff->seqno, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_FENCE_WARN(f, fmt, args...) \
|
||||
do { \
|
||||
struct dma_fence *__ff = (f); \
|
||||
pr_warn("f %llu#%llu: " fmt, __ff->context, __ff->seqno,\
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
#define DMA_FENCE_ERR(f, fmt, args...) \
|
||||
do { \
|
||||
struct dma_fence *__ff = (f); \
|
||||
pr_err("f %llu#%llu: " fmt, __ff->context, __ff->seqno, \
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
#endif /* __LINUX_DMA_FENCE_H */
|
||||
|
|
|
|||
|
|
@ -62,16 +62,90 @@ struct dma_resv_list {
|
|||
|
||||
/**
|
||||
* struct dma_resv - a reservation object manages fences for a buffer
|
||||
* @lock: update side lock
|
||||
* @seq: sequence count for managing RCU read-side synchronization
|
||||
* @fence_excl: the exclusive fence, if there is one currently
|
||||
* @fence: list of current shared fences
|
||||
*
|
||||
* There are multiple uses for this, with sometimes slightly different rules in
|
||||
* how the fence slots are used.
|
||||
*
|
||||
* One use is to synchronize cross-driver access to a struct dma_buf, either for
|
||||
* dynamic buffer management or just to handle implicit synchronization between
|
||||
* different users of the buffer in userspace. See &dma_buf.resv for a more
|
||||
* in-depth discussion.
|
||||
*
|
||||
* The other major use is to manage access and locking within a driver in a
|
||||
* buffer based memory manager. struct ttm_buffer_object is the canonical
|
||||
* example here, since this is where reservation objects originated from. But
|
||||
* use in drivers is spreading and some drivers also manage struct
|
||||
* drm_gem_object with the same scheme.
|
||||
*/
|
||||
struct dma_resv {
|
||||
/**
|
||||
* @lock:
|
||||
*
|
||||
* Update side lock. Don't use directly, instead use the wrapper
|
||||
* functions like dma_resv_lock() and dma_resv_unlock().
|
||||
*
|
||||
* Drivers which use the reservation object to manage memory dynamically
|
||||
* also use this lock to protect buffer object state like placement,
|
||||
* allocation policies or throughout command submission.
|
||||
*/
|
||||
struct ww_mutex lock;
|
||||
|
||||
/**
|
||||
* @seq:
|
||||
*
|
||||
* Sequence count for managing RCU read-side synchronization, allows
|
||||
* read-only access to @fence_excl and @fence while ensuring we take a
|
||||
* consistent snapshot.
|
||||
*/
|
||||
seqcount_ww_mutex_t seq;
|
||||
|
||||
/**
|
||||
* @fence_excl:
|
||||
*
|
||||
* The exclusive fence, if there is one currently.
|
||||
*
|
||||
* There are two ways to update this fence:
|
||||
*
|
||||
* - First by calling dma_resv_add_excl_fence(), which replaces all
|
||||
* fences attached to the reservation object. To guarantee that no
|
||||
* fences are lost, this new fence must signal only after all previous
|
||||
* fences, both shared and exclusive, have signalled. In some cases it
|
||||
* is convenient to achieve that by attaching a struct dma_fence_array
|
||||
* with all the new and old fences.
|
||||
*
|
||||
* - Alternatively the fence can be set directly, which leaves the
|
||||
* shared fences unchanged. To guarantee that no fences are lost, this
|
||||
* new fence must signal only after the previous exclusive fence has
|
||||
* signalled. Since the shared fences are staying intact, it is not
|
||||
* necessary to maintain any ordering against those. If semantically
|
||||
* only a new access is added without actually treating the previous
|
||||
* one as a dependency the exclusive fences can be strung together
|
||||
* using struct dma_fence_chain.
|
||||
*
|
||||
* Note that actual semantics of what an exclusive or shared fence mean
|
||||
* is defined by the user, for reservation objects shared across drivers
|
||||
* see &dma_buf.resv.
|
||||
*/
|
||||
struct dma_fence __rcu *fence_excl;
|
||||
|
||||
/**
|
||||
* @fence:
|
||||
*
|
||||
* List of current shared fences.
|
||||
*
|
||||
* There are no ordering constraints of shared fences against the
|
||||
* exclusive fence slot. If a waiter needs to wait for all access, it
|
||||
* has to wait for both sets of fences to signal.
|
||||
*
|
||||
* A new fence is added by calling dma_resv_add_shared_fence(). Since
|
||||
* this often needs to be done past the point of no return in command
|
||||
* submission it cannot fail, and therefore sufficient slots need to be
|
||||
* reserved by calling dma_resv_reserve_shared().
|
||||
*
|
||||
* Note that actual semantics of what an exclusive or shared fence mean
|
||||
* is defined by the user, for reservation objects shared across drivers
|
||||
* see &dma_buf.resv.
|
||||
*/
|
||||
struct dma_resv_list __rcu *fence;
|
||||
};
|
||||
|
||||
|
|
@ -98,6 +172,13 @@ static inline void dma_resv_reset_shared_max(struct dma_resv *obj) {}
|
|||
* undefined order, a #ww_acquire_ctx is passed to unwind if a cycle
|
||||
* is detected. See ww_mutex_lock() and ww_acquire_init(). A reservation
|
||||
* object may be locked by itself by passing NULL as @ctx.
|
||||
*
|
||||
* When a die situation is indicated by returning -EDEADLK all locks held by
|
||||
* @ctx must be unlocked and then dma_resv_lock_slow() called on @obj.
|
||||
*
|
||||
* Unlocked by calling dma_resv_unlock().
|
||||
*
|
||||
* See also dma_resv_lock_interruptible() for the interruptible variant.
|
||||
*/
|
||||
static inline int dma_resv_lock(struct dma_resv *obj,
|
||||
struct ww_acquire_ctx *ctx)
|
||||
|
|
@ -119,6 +200,12 @@ static inline int dma_resv_lock(struct dma_resv *obj,
|
|||
* undefined order, a #ww_acquire_ctx is passed to unwind if a cycle
|
||||
* is detected. See ww_mutex_lock() and ww_acquire_init(). A reservation
|
||||
* object may be locked by itself by passing NULL as @ctx.
|
||||
*
|
||||
* When a die situation is indicated by returning -EDEADLK all locks held by
|
||||
* @ctx must be unlocked and then dma_resv_lock_slow_interruptible() called on
|
||||
* @obj.
|
||||
*
|
||||
* Unlocked by calling dma_resv_unlock().
|
||||
*/
|
||||
static inline int dma_resv_lock_interruptible(struct dma_resv *obj,
|
||||
struct ww_acquire_ctx *ctx)
|
||||
|
|
@ -134,6 +221,8 @@ static inline int dma_resv_lock_interruptible(struct dma_resv *obj,
|
|||
* Acquires the reservation object after a die case. This function
|
||||
* will sleep until the lock becomes available. See dma_resv_lock() as
|
||||
* well.
|
||||
*
|
||||
* See also dma_resv_lock_slow_interruptible() for the interruptible variant.
|
||||
*/
|
||||
static inline void dma_resv_lock_slow(struct dma_resv *obj,
|
||||
struct ww_acquire_ctx *ctx)
|
||||
|
|
@ -167,7 +256,7 @@ static inline int dma_resv_lock_slow_interruptible(struct dma_resv *obj,
|
|||
* if they overlap with a writer.
|
||||
*
|
||||
* Also note that since no context is provided, no deadlock protection is
|
||||
* possible.
|
||||
* possible, which is also not needed for a trylock.
|
||||
*
|
||||
* Returns true if the lock was acquired, false otherwise.
|
||||
*/
|
||||
|
|
@ -193,6 +282,11 @@ static inline bool dma_resv_is_locked(struct dma_resv *obj)
|
|||
*
|
||||
* Returns the context used to lock a reservation object or NULL if no context
|
||||
* was used or the object is not locked at all.
|
||||
*
|
||||
* WARNING: This interface is pretty horrible, but TTM needs it because it
|
||||
* doesn't pass the struct ww_acquire_ctx around in some very long callchains.
|
||||
* Everyone else just uses it to check whether they're holding a reservation or
|
||||
* not.
|
||||
*/
|
||||
static inline struct ww_acquire_ctx *dma_resv_locking_ctx(struct dma_resv *obj)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,109 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* seqno-fence, using a dma-buf to synchronize fencing
|
||||
*
|
||||
* Copyright (C) 2012 Texas Instruments
|
||||
* Copyright (C) 2012 Canonical Ltd
|
||||
* Authors:
|
||||
* Rob Clark <robdclark@gmail.com>
|
||||
* Maarten Lankhorst <maarten.lankhorst@canonical.com>
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_SEQNO_FENCE_H
|
||||
#define __LINUX_SEQNO_FENCE_H
|
||||
|
||||
#include <linux/dma-fence.h>
|
||||
#include <linux/dma-buf.h>
|
||||
|
||||
enum seqno_fence_condition {
|
||||
SEQNO_FENCE_WAIT_GEQUAL,
|
||||
SEQNO_FENCE_WAIT_NONZERO
|
||||
};
|
||||
|
||||
struct seqno_fence {
|
||||
struct dma_fence base;
|
||||
|
||||
const struct dma_fence_ops *ops;
|
||||
struct dma_buf *sync_buf;
|
||||
uint32_t seqno_ofs;
|
||||
enum seqno_fence_condition condition;
|
||||
};
|
||||
|
||||
extern const struct dma_fence_ops seqno_fence_ops;
|
||||
|
||||
/**
|
||||
* to_seqno_fence - cast a fence to a seqno_fence
|
||||
* @fence: fence to cast to a seqno_fence
|
||||
*
|
||||
* Returns NULL if the fence is not a seqno_fence,
|
||||
* or the seqno_fence otherwise.
|
||||
*/
|
||||
static inline struct seqno_fence *
|
||||
to_seqno_fence(struct dma_fence *fence)
|
||||
{
|
||||
if (fence->ops != &seqno_fence_ops)
|
||||
return NULL;
|
||||
return container_of(fence, struct seqno_fence, base);
|
||||
}
|
||||
|
||||
/**
|
||||
* seqno_fence_init - initialize a seqno fence
|
||||
* @fence: seqno_fence to initialize
|
||||
* @lock: pointer to spinlock to use for fence
|
||||
* @sync_buf: buffer containing the memory location to signal on
|
||||
* @context: the execution context this fence is a part of
|
||||
* @seqno_ofs: the offset within @sync_buf
|
||||
* @seqno: the sequence # to signal on
|
||||
* @cond: fence wait condition
|
||||
* @ops: the fence_ops for operations on this seqno fence
|
||||
*
|
||||
* This function initializes a struct seqno_fence with passed parameters,
|
||||
* and takes a reference on sync_buf which is released on fence destruction.
|
||||
*
|
||||
* A seqno_fence is a dma_fence which can complete in software when
|
||||
* enable_signaling is called, but it also completes when
|
||||
* (s32)((sync_buf)[seqno_ofs] - seqno) >= 0 is true
|
||||
*
|
||||
* The seqno_fence will take a refcount on the sync_buf until it's
|
||||
* destroyed, but actual lifetime of sync_buf may be longer if one of the
|
||||
* callers take a reference to it.
|
||||
*
|
||||
* Certain hardware have instructions to insert this type of wait condition
|
||||
* in the command stream, so no intervention from software would be needed.
|
||||
* This type of fence can be destroyed before completed, however a reference
|
||||
* on the sync_buf dma-buf can be taken. It is encouraged to re-use the same
|
||||
* dma-buf for sync_buf, since mapping or unmapping the sync_buf to the
|
||||
* device's vm can be expensive.
|
||||
*
|
||||
* It is recommended for creators of seqno_fence to call dma_fence_signal()
|
||||
* before destruction. This will prevent possible issues from wraparound at
|
||||
* time of issue vs time of check, since users can check dma_fence_is_signaled()
|
||||
* before submitting instructions for the hardware to wait on the fence.
|
||||
* However, when ops.enable_signaling is not called, it doesn't have to be
|
||||
* done as soon as possible, just before there's any real danger of seqno
|
||||
* wraparound.
|
||||
*/
|
||||
static inline void
|
||||
seqno_fence_init(struct seqno_fence *fence, spinlock_t *lock,
|
||||
struct dma_buf *sync_buf, uint32_t context,
|
||||
uint32_t seqno_ofs, uint32_t seqno,
|
||||
enum seqno_fence_condition cond,
|
||||
const struct dma_fence_ops *ops)
|
||||
{
|
||||
BUG_ON(!fence || !sync_buf || !ops);
|
||||
BUG_ON(!ops->wait || !ops->enable_signaling ||
|
||||
!ops->get_driver_name || !ops->get_timeline_name);
|
||||
|
||||
/*
|
||||
* ops is used in dma_fence_init for get_driver_name, so needs to be
|
||||
* initialized first
|
||||
*/
|
||||
fence->ops = ops;
|
||||
dma_fence_init(&fence->base, &seqno_fence_ops, lock, context, seqno);
|
||||
get_dma_buf(sync_buf);
|
||||
fence->sync_buf = sync_buf;
|
||||
fence->seqno_ofs = seqno_ofs;
|
||||
fence->condition = cond;
|
||||
}
|
||||
|
||||
#endif /* __LINUX_SEQNO_FENCE_H */
|
||||
|
|
@ -93,4 +93,5 @@ extern void register_shrinker_prepared(struct shrinker *shrinker);
|
|||
extern int register_shrinker(struct shrinker *shrinker);
|
||||
extern void unregister_shrinker(struct shrinker *shrinker);
|
||||
extern void free_prealloced_shrinker(struct shrinker *shrinker);
|
||||
extern void synchronize_shrinkers(void);
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue