mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-17 15:08:54 +00:00
Minor dma-buf updates for 4.7:
- use of vma_pages instead of explicit computation. - DocBook and headerdoc updates for dma-buf. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXTnlHAAoJEAG+/NWsLn5b/NUQAJHV0vNseAmwNDU02nUX/2bK h6nTLFzGsc8jiRfbay9WcQWMOHOmyGyT8llwJxdgDqRHV5THCWZ/MaMwGLUPjK80 INN2GIq6unvuRSUcTRsG+DahOIbqIOGtBzd7rBizxW7afk/Y2aJU9JWyQGKPqVVb fb6X9/GNKNXsQQUx6oF2mQIexso9F4++jN0S9oJGQL23MyR05leNmYFCPv1hwjdF Jc39SLkPqGe0v31zwl0QU0wB/8Ay2xY68GskIVGxohOj36RxTbPs74XJlnAUrZAX zNAzdcynGiBqMn4VE+4nWAWbSQnHObJkDKuuZNRLgwQZbFygDpfzIBWAsnfTROAE HJL1lsrCRcAHgcwoMu/ZSBsLSrR4nmpeqBPZVii9G62SCLO0YysTa6LKo2faGczF 1po6ZX+TFmRRmUffLaq5u4wlEtnma/HpDCeydYX8T2NGWt7pRBdpWk4j42SFAV1G SdkzjLzhIS/EjxEvHWZItQkq0JMpiPfh3AxYcKhd/oMOcBizDn0+BY6f6FgtRG9g 7JCzJ0/RJXHyfAJfapmNphb7zie/Pltzb1gVXarS314QtalLika4C35GUnC7vcDt AB7CNq63fMsLvQ9KLhO7DXztVC08zwk5jyRR7hmIJVF0hgVNYEnF3EGyVtYA5THI bUl+iSQrBVI08mxDxCM2 =XMBK -----END PGP SIGNATURE----- Merge tag 'dma-buf-for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sumits/dma-buf Pull dma-buf updates from Sumit Semwal: - use of vma_pages instead of explicit computation - DocBook and headerdoc updates for dma-buf * tag 'dma-buf-for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sumits/dma-buf: dma-buf: use vma_pages() fence: add missing descriptions for fence doc: update/fixup dma-buf related DocBook reservation: add headerdoc comments dma-buf: headerdoc fixes
This commit is contained in:
commit
ebb8cb2bae
@ -128,16 +128,44 @@ X!Edrivers/base/interface.c
|
|||||||
!Edrivers/base/platform.c
|
!Edrivers/base/platform.c
|
||||||
!Edrivers/base/bus.c
|
!Edrivers/base/bus.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>Device Drivers DMA Management</title>
|
<sect1>
|
||||||
|
<title>Buffer Sharing and Synchronization</title>
|
||||||
|
<para>
|
||||||
|
The dma-buf subsystem provides the framework for sharing buffers
|
||||||
|
for hardware (DMA) access across multiple device drivers and
|
||||||
|
subsystems, and for synchronizing asynchronous hardware access.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This is used, for example, by drm "prime" multi-GPU support, but
|
||||||
|
is of course not limited to GPU use cases.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
The three main components of this are: (1) dma-buf, representing
|
||||||
|
a sg_table and exposed to userspace as a file descriptor to allow
|
||||||
|
passing between devices, (2) fence, which provides a mechanism
|
||||||
|
to signal when one device as finished access, and (3) reservation,
|
||||||
|
which manages the shared or exclusive fence(s) associated with
|
||||||
|
the buffer.
|
||||||
|
</para>
|
||||||
|
<sect2><title>dma-buf</title>
|
||||||
!Edrivers/dma-buf/dma-buf.c
|
!Edrivers/dma-buf/dma-buf.c
|
||||||
!Edrivers/dma-buf/fence.c
|
!Iinclude/linux/dma-buf.h
|
||||||
!Edrivers/dma-buf/seqno-fence.c
|
</sect2>
|
||||||
!Iinclude/linux/fence.h
|
<sect2><title>reservation</title>
|
||||||
!Iinclude/linux/seqno-fence.h
|
!Pdrivers/dma-buf/reservation.c Reservation Object Overview
|
||||||
!Edrivers/dma-buf/reservation.c
|
!Edrivers/dma-buf/reservation.c
|
||||||
!Iinclude/linux/reservation.h
|
!Iinclude/linux/reservation.h
|
||||||
|
</sect2>
|
||||||
|
<sect2><title>fence</title>
|
||||||
|
!Edrivers/dma-buf/fence.c
|
||||||
|
!Iinclude/linux/fence.h
|
||||||
|
!Edrivers/dma-buf/seqno-fence.c
|
||||||
|
!Iinclude/linux/seqno-fence.h
|
||||||
!Edrivers/dma-buf/sync_file.c
|
!Edrivers/dma-buf/sync_file.c
|
||||||
!Iinclude/linux/sync_file.h
|
!Iinclude/linux/sync_file.h
|
||||||
|
</sect2>
|
||||||
|
</sect1>
|
||||||
|
<sect1><title>Device Drivers DMA Management</title>
|
||||||
!Edrivers/base/dma-coherent.c
|
!Edrivers/base/dma-coherent.c
|
||||||
!Edrivers/base/dma-mapping.c
|
!Edrivers/base/dma-mapping.c
|
||||||
</sect1>
|
</sect1>
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/reservation.h>
|
#include <linux/reservation.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
|
||||||
#include <uapi/linux/dma-buf.h>
|
#include <uapi/linux/dma-buf.h>
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
|
|||||||
dmabuf = file->private_data;
|
dmabuf = file->private_data;
|
||||||
|
|
||||||
/* check for overflowing the buffer's size */
|
/* check for overflowing the buffer's size */
|
||||||
if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
|
if (vma->vm_pgoff + vma_pages(vma) >
|
||||||
dmabuf->size >> PAGE_SHIFT)
|
dmabuf->size >> PAGE_SHIFT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -723,11 +724,11 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* check for offset overflow */
|
/* check for offset overflow */
|
||||||
if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < pgoff)
|
if (pgoff + vma_pages(vma) < pgoff)
|
||||||
return -EOVERFLOW;
|
return -EOVERFLOW;
|
||||||
|
|
||||||
/* check for overflowing the buffer's size */
|
/* check for overflowing the buffer's size */
|
||||||
if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
|
if (pgoff + vma_pages(vma) >
|
||||||
dmabuf->size >> PAGE_SHIFT)
|
dmabuf->size >> PAGE_SHIFT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -35,6 +35,17 @@
|
|||||||
#include <linux/reservation.h>
|
#include <linux/reservation.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOC: Reservation Object Overview
|
||||||
|
*
|
||||||
|
* The reservation object provides a mechanism to manage shared and
|
||||||
|
* exclusive fences associated with a buffer. A reservation object
|
||||||
|
* can have attached one exclusive fence (normally associated with
|
||||||
|
* write operations) or N shared fences (read operations). The RCU
|
||||||
|
* mechanism is used to protect read access to fences from locked
|
||||||
|
* write-side updates.
|
||||||
|
*/
|
||||||
|
|
||||||
DEFINE_WW_CLASS(reservation_ww_class);
|
DEFINE_WW_CLASS(reservation_ww_class);
|
||||||
EXPORT_SYMBOL(reservation_ww_class);
|
EXPORT_SYMBOL(reservation_ww_class);
|
||||||
|
|
||||||
@ -43,9 +54,17 @@ EXPORT_SYMBOL(reservation_seqcount_class);
|
|||||||
|
|
||||||
const char reservation_seqcount_string[] = "reservation_seqcount";
|
const char reservation_seqcount_string[] = "reservation_seqcount";
|
||||||
EXPORT_SYMBOL(reservation_seqcount_string);
|
EXPORT_SYMBOL(reservation_seqcount_string);
|
||||||
/*
|
|
||||||
* Reserve space to add a shared fence to a reservation_object,
|
/**
|
||||||
* must be called with obj->lock held.
|
* reservation_object_reserve_shared - Reserve space to add a shared
|
||||||
|
* fence to a reservation_object.
|
||||||
|
* @obj: reservation object
|
||||||
|
*
|
||||||
|
* Should be called before reservation_object_add_shared_fence(). Must
|
||||||
|
* be called with obj->lock held.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Zero for success, or -errno
|
||||||
*/
|
*/
|
||||||
int reservation_object_reserve_shared(struct reservation_object *obj)
|
int reservation_object_reserve_shared(struct reservation_object *obj)
|
||||||
{
|
{
|
||||||
@ -180,7 +199,11 @@ done:
|
|||||||
fence_put(old_fence);
|
fence_put(old_fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* reservation_object_add_shared_fence - Add a fence to a shared slot
|
||||||
|
* @obj: the reservation object
|
||||||
|
* @fence: the shared fence to add
|
||||||
|
*
|
||||||
* Add a fence to a shared slot, obj->lock must be held, and
|
* Add a fence to a shared slot, obj->lock must be held, and
|
||||||
* reservation_object_reserve_shared_fence has been called.
|
* reservation_object_reserve_shared_fence has been called.
|
||||||
*/
|
*/
|
||||||
@ -200,6 +223,13 @@ void reservation_object_add_shared_fence(struct reservation_object *obj,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(reservation_object_add_shared_fence);
|
EXPORT_SYMBOL(reservation_object_add_shared_fence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_add_excl_fence - Add an exclusive fence.
|
||||||
|
* @obj: the reservation object
|
||||||
|
* @fence: the shared fence to add
|
||||||
|
*
|
||||||
|
* Add a fence to the exclusive slot. The obj->lock must be held.
|
||||||
|
*/
|
||||||
void reservation_object_add_excl_fence(struct reservation_object *obj,
|
void reservation_object_add_excl_fence(struct reservation_object *obj,
|
||||||
struct fence *fence)
|
struct fence *fence)
|
||||||
{
|
{
|
||||||
@ -233,6 +263,18 @@ void reservation_object_add_excl_fence(struct reservation_object *obj,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(reservation_object_add_excl_fence);
|
EXPORT_SYMBOL(reservation_object_add_excl_fence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_get_fences_rcu - Get an object's shared and exclusive
|
||||||
|
* fences without update side lock held
|
||||||
|
* @obj: the reservation object
|
||||||
|
* @pfence_excl: the returned exclusive fence (or NULL)
|
||||||
|
* @pshared_count: the number of shared fences returned
|
||||||
|
* @pshared: the array of shared fence ptrs returned (array is krealloc'd to
|
||||||
|
* the required size, and must be freed by caller)
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Zero or -errno
|
||||||
|
*/
|
||||||
int reservation_object_get_fences_rcu(struct reservation_object *obj,
|
int reservation_object_get_fences_rcu(struct reservation_object *obj,
|
||||||
struct fence **pfence_excl,
|
struct fence **pfence_excl,
|
||||||
unsigned *pshared_count,
|
unsigned *pshared_count,
|
||||||
@ -319,6 +361,18 @@ unlock:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(reservation_object_get_fences_rcu);
|
EXPORT_SYMBOL_GPL(reservation_object_get_fences_rcu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_wait_timeout_rcu - Wait on reservation's objects
|
||||||
|
* shared and/or exclusive fences.
|
||||||
|
* @obj: the reservation object
|
||||||
|
* @wait_all: if true, wait on all fences, else wait on just exclusive fence
|
||||||
|
* @intr: if true, do interruptible wait
|
||||||
|
* @timeout: timeout value in jiffies or zero to return immediately
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
|
||||||
|
* greater than zer on success.
|
||||||
|
*/
|
||||||
long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
|
long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
|
||||||
bool wait_all, bool intr,
|
bool wait_all, bool intr,
|
||||||
unsigned long timeout)
|
unsigned long timeout)
|
||||||
@ -416,6 +470,16 @@ reservation_object_test_signaled_single(struct fence *passed_fence)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_test_signaled_rcu - Test if a reservation object's
|
||||||
|
* fences have been signaled.
|
||||||
|
* @obj: the reservation object
|
||||||
|
* @test_all: if true, test all fences, otherwise only test the exclusive
|
||||||
|
* fence
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* true if all fences signaled, else false
|
||||||
|
*/
|
||||||
bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
|
bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
|
||||||
bool test_all)
|
bool test_all)
|
||||||
{
|
{
|
||||||
|
@ -112,19 +112,24 @@ struct dma_buf_ops {
|
|||||||
* @file: file pointer used for sharing buffers across, and for refcounting.
|
* @file: file pointer used for sharing buffers across, and for refcounting.
|
||||||
* @attachments: list of dma_buf_attachment that denotes all devices attached.
|
* @attachments: list of dma_buf_attachment that denotes all devices attached.
|
||||||
* @ops: dma_buf_ops associated with this buffer object.
|
* @ops: dma_buf_ops associated with this buffer object.
|
||||||
|
* @lock: used internally to serialize list manipulation, attach/detach and vmap/unmap
|
||||||
|
* @vmapping_counter: used internally to refcnt the vmaps
|
||||||
|
* @vmap_ptr: the current vmap ptr if vmapping_counter > 0
|
||||||
* @exp_name: name of the exporter; useful for debugging.
|
* @exp_name: name of the exporter; useful for debugging.
|
||||||
* @owner: pointer to exporter module; used for refcounting when exporter is a
|
* @owner: pointer to exporter module; used for refcounting when exporter is a
|
||||||
* kernel module.
|
* kernel module.
|
||||||
* @list_node: node for dma_buf accounting and debugging.
|
* @list_node: node for dma_buf accounting and debugging.
|
||||||
* @priv: exporter specific private data for this buffer object.
|
* @priv: exporter specific private data for this buffer object.
|
||||||
* @resv: reservation object linked to this dma-buf
|
* @resv: reservation object linked to this dma-buf
|
||||||
|
* @poll: for userspace poll support
|
||||||
|
* @cb_excl: for userspace poll support
|
||||||
|
* @cb_shared: for userspace poll support
|
||||||
*/
|
*/
|
||||||
struct dma_buf {
|
struct dma_buf {
|
||||||
size_t size;
|
size_t size;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
struct list_head attachments;
|
struct list_head attachments;
|
||||||
const struct dma_buf_ops *ops;
|
const struct dma_buf_ops *ops;
|
||||||
/* mutex to serialize list manipulation, attach/detach and vmap/unmap */
|
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
unsigned vmapping_counter;
|
unsigned vmapping_counter;
|
||||||
void *vmap_ptr;
|
void *vmap_ptr;
|
||||||
@ -188,9 +193,11 @@ struct dma_buf_export_info {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* helper macro for exporters; zeros and fills in most common values
|
* helper macro for exporters; zeros and fills in most common values
|
||||||
|
*
|
||||||
|
* @name: export-info name
|
||||||
*/
|
*/
|
||||||
#define DEFINE_DMA_BUF_EXPORT_INFO(a) \
|
#define DEFINE_DMA_BUF_EXPORT_INFO(name) \
|
||||||
struct dma_buf_export_info a = { .exp_name = KBUILD_MODNAME, \
|
struct dma_buf_export_info name = { .exp_name = KBUILD_MODNAME, \
|
||||||
.owner = THIS_MODULE }
|
.owner = THIS_MODULE }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,6 +49,8 @@ struct fence_cb;
|
|||||||
* @timestamp: Timestamp when the fence was signaled.
|
* @timestamp: Timestamp when the fence was signaled.
|
||||||
* @status: Optional, only valid if < 0, must be set before calling
|
* @status: Optional, only valid if < 0, must be set before calling
|
||||||
* fence_signal, indicates that the fence has completed with an error.
|
* fence_signal, indicates that the fence has completed with an error.
|
||||||
|
* @child_list: list of children fences
|
||||||
|
* @active_list: list of active fences
|
||||||
*
|
*
|
||||||
* the flags member must be manipulated and read using the appropriate
|
* the flags member must be manipulated and read using the appropriate
|
||||||
* atomic ops (bit_*), so taking the spinlock will not be needed most
|
* atomic ops (bit_*), so taking the spinlock will not be needed most
|
||||||
|
@ -49,12 +49,27 @@ extern struct ww_class reservation_ww_class;
|
|||||||
extern struct lock_class_key reservation_seqcount_class;
|
extern struct lock_class_key reservation_seqcount_class;
|
||||||
extern const char reservation_seqcount_string[];
|
extern const char reservation_seqcount_string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct reservation_object_list - a list of shared fences
|
||||||
|
* @rcu: for internal use
|
||||||
|
* @shared_count: table of shared fences
|
||||||
|
* @shared_max: for growing shared fence table
|
||||||
|
* @shared: shared fence table
|
||||||
|
*/
|
||||||
struct reservation_object_list {
|
struct reservation_object_list {
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
u32 shared_count, shared_max;
|
u32 shared_count, shared_max;
|
||||||
struct fence __rcu *shared[];
|
struct fence __rcu *shared[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct reservation_object - 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
|
||||||
|
* @staged: staged copy of shared fences for RCU updates
|
||||||
|
*/
|
||||||
struct reservation_object {
|
struct reservation_object {
|
||||||
struct ww_mutex lock;
|
struct ww_mutex lock;
|
||||||
seqcount_t seq;
|
seqcount_t seq;
|
||||||
@ -68,6 +83,10 @@ struct reservation_object {
|
|||||||
#define reservation_object_assert_held(obj) \
|
#define reservation_object_assert_held(obj) \
|
||||||
lockdep_assert_held(&(obj)->lock.base)
|
lockdep_assert_held(&(obj)->lock.base)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_init - initialize a reservation object
|
||||||
|
* @obj: the reservation object
|
||||||
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
reservation_object_init(struct reservation_object *obj)
|
reservation_object_init(struct reservation_object *obj)
|
||||||
{
|
{
|
||||||
@ -79,6 +98,10 @@ reservation_object_init(struct reservation_object *obj)
|
|||||||
obj->staged = NULL;
|
obj->staged = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_fini - destroys a reservation object
|
||||||
|
* @obj: the reservation object
|
||||||
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
reservation_object_fini(struct reservation_object *obj)
|
reservation_object_fini(struct reservation_object *obj)
|
||||||
{
|
{
|
||||||
@ -106,6 +129,14 @@ reservation_object_fini(struct reservation_object *obj)
|
|||||||
ww_mutex_destroy(&obj->lock);
|
ww_mutex_destroy(&obj->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_get_list - get the reservation object's
|
||||||
|
* shared fence list, with update-side lock held
|
||||||
|
* @obj: the reservation object
|
||||||
|
*
|
||||||
|
* Returns the shared fence list. Does NOT take references to
|
||||||
|
* the fence. The obj->lock must be held.
|
||||||
|
*/
|
||||||
static inline struct reservation_object_list *
|
static inline struct reservation_object_list *
|
||||||
reservation_object_get_list(struct reservation_object *obj)
|
reservation_object_get_list(struct reservation_object *obj)
|
||||||
{
|
{
|
||||||
@ -113,6 +144,17 @@ reservation_object_get_list(struct reservation_object *obj)
|
|||||||
reservation_object_held(obj));
|
reservation_object_held(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_get_excl - get the reservation object's
|
||||||
|
* exclusive fence, with update-side lock held
|
||||||
|
* @obj: the reservation object
|
||||||
|
*
|
||||||
|
* Returns the exclusive fence (if any). Does NOT take a
|
||||||
|
* reference. The obj->lock must be held.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* The exclusive fence or NULL
|
||||||
|
*/
|
||||||
static inline struct fence *
|
static inline struct fence *
|
||||||
reservation_object_get_excl(struct reservation_object *obj)
|
reservation_object_get_excl(struct reservation_object *obj)
|
||||||
{
|
{
|
||||||
@ -120,6 +162,17 @@ reservation_object_get_excl(struct reservation_object *obj)
|
|||||||
reservation_object_held(obj));
|
reservation_object_held(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reservation_object_get_excl_rcu - get the reservation object's
|
||||||
|
* exclusive fence, without lock held.
|
||||||
|
* @obj: the reservation object
|
||||||
|
*
|
||||||
|
* If there is an exclusive fence, this atomically increments it's
|
||||||
|
* reference count and returns it.
|
||||||
|
*
|
||||||
|
* RETURNS
|
||||||
|
* The exclusive fence or NULL if none
|
||||||
|
*/
|
||||||
static inline struct fence *
|
static inline struct fence *
|
||||||
reservation_object_get_excl_rcu(struct reservation_object *obj)
|
reservation_object_get_excl_rcu(struct reservation_object *obj)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user