Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

add spin_lock_irqsave_nolockdep and mutex type MUTEX_NOLOCKDEP #480

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/linux/file_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ spl_filp_fallocate(struct file *fp, int mode, loff_t offset, loff_t len)
#define spl_filp_fsync(fp, sync) vfs_fsync(fp, (fp)->f_dentry, sync)
#endif /* HAVE_2ARGS_VFS_FSYNC */

#define spl_inode_lock(ip) mutex_lock(&(ip)->i_mutex)
#define spl_inode_lock(ip) mutex_lock_nested(&(ip)->i_mutex, I_MUTEX_PARENT)
#define spl_inode_unlock(ip) mutex_unlock(&(ip)->i_mutex)

#endif /* SPL_FILE_COMPAT_H */
Expand Down
42 changes: 40 additions & 2 deletions include/sys/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,22 @@
#include <sys/types.h>
#include <linux/mutex.h>
#include <linux/compiler_compat.h>
#include <linux/lockdep.h>

typedef enum {
MUTEX_DEFAULT = 0,
MUTEX_SPIN = 1,
MUTEX_ADAPTIVE = 2
MUTEX_ADAPTIVE = 2,
MUTEX_NOLOCKDEP = 3
} kmutex_type_t;

typedef struct {
struct mutex m_mutex;
spinlock_t m_lock; /* used for serializing mutex_exit */
kthread_t *m_owner;
#ifdef CONFIG_LOCKDEP
kmutex_type_t m_type;
#endif /* CONFIG_LOCKDEP */
} kmutex_t;

#define MUTEX(mp) (&((mp)->m_mutex))
Expand All @@ -60,6 +65,30 @@ spl_mutex_clear_owner(kmutex_t *mp)
#define MUTEX_HELD(mp) mutex_owned(mp)
#define MUTEX_NOT_HELD(mp) (!MUTEX_HELD(mp))

#ifdef CONFIG_LOCKDEP
static inline void
spl_mutex_set_type(kmutex_t *mp, kmutex_type_t type)
{
mp->m_type = type;
}
static inline void
spl_mutex_lockdep_off_maybe(kmutex_t *mp) \
{ \
if (mp && mp->m_type == MUTEX_NOLOCKDEP) \
lockdep_off(); \
}
static inline void
spl_mutex_lockdep_on_maybe(kmutex_t *mp) \
{ \
if (mp && mp->m_type == MUTEX_NOLOCKDEP) \
lockdep_on(); \
}
#else /* CONFIG_LOCKDEP */
#define spl_mutex_set_type(mp, type)
#define spl_mutex_lockdep_off_maybe(mp)
#define spl_mutex_lockdep_on_maybe(mp)
#endif /* CONFIG_LOCKDEP */

/*
* The following functions must be a #define and not static inline.
* This ensures that the native linux mutex functions (lock/unlock)
Expand All @@ -70,11 +99,12 @@ spl_mutex_clear_owner(kmutex_t *mp)
#define mutex_init(mp, name, type, ibc) \
{ \
static struct lock_class_key __key; \
ASSERT(type == MUTEX_DEFAULT); \
ASSERT(type == MUTEX_DEFAULT || type == MUTEX_NOLOCKDEP); \
\
__mutex_init(MUTEX(mp), (name) ? (#name) : (#mp), &__key); \
spin_lock_init(&(mp)->m_lock); \
spl_mutex_clear_owner(mp); \
spl_mutex_set_type(mp, type); \
}

#undef mutex_destroy
Expand All @@ -87,8 +117,10 @@ spl_mutex_clear_owner(kmutex_t *mp)
({ \
int _rc_; \
\
spl_mutex_lockdep_off_maybe(mp); \
if ((_rc_ = mutex_trylock(MUTEX(mp))) == 1) \
spl_mutex_set_owner(mp); \
spl_mutex_lockdep_on_maybe(mp); \
\
_rc_; \
})
Expand All @@ -97,14 +129,18 @@ spl_mutex_clear_owner(kmutex_t *mp)
#define mutex_enter_nested(mp, subclass) \
{ \
ASSERT3P(mutex_owner(mp), !=, current); \
spl_mutex_lockdep_off_maybe(mp); \
mutex_lock_nested(MUTEX(mp), (subclass)); \
spl_mutex_lockdep_on_maybe(mp); \
spl_mutex_set_owner(mp); \
}
#else /* CONFIG_DEBUG_LOCK_ALLOC */
#define mutex_enter_nested(mp, subclass) \
{ \
ASSERT3P(mutex_owner(mp), !=, current); \
spl_mutex_lockdep_off_maybe(mp); \
mutex_lock(MUTEX(mp)); \
spl_mutex_lockdep_on_maybe(mp); \
spl_mutex_set_owner(mp); \
}
#endif /* CONFIG_DEBUG_LOCK_ALLOC */
Expand Down Expand Up @@ -132,10 +168,12 @@ spl_mutex_clear_owner(kmutex_t *mp)
*/
#define mutex_exit(mp) \
{ \
spl_mutex_lockdep_off_maybe(mp); \
spin_lock(&(mp)->m_lock); \
spl_mutex_clear_owner(mp); \
mutex_unlock(MUTEX(mp)); \
spin_unlock(&(mp)->m_lock); \
spl_mutex_lockdep_on_maybe(mp); \
}

int spl_mutex_init(void);
Expand Down
42 changes: 41 additions & 1 deletion include/sys/rwlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@

typedef enum {
RW_DRIVER = 2,
RW_DEFAULT = 4
RW_DEFAULT = 4,
RW_NOLOCKDEP = 5
} krw_type_t;

typedef enum {
Expand All @@ -49,6 +50,9 @@ typedef struct {
#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
kthread_t *rw_owner;
#endif
#ifdef CONFIG_LOCKDEP
krw_type_t rw_type;
#endif /* CONFIG_LOCKDEP */
} krwlock_t;

#define SEM(rwp) (&(rwp)->rw_rwlock)
Expand Down Expand Up @@ -83,6 +87,30 @@ rw_owner(krwlock_t *rwp)
#endif
}

#ifdef CONFIG_LOCKDEP
static inline void
spl_rw_set_type(krwlock_t *rwp, krw_type_t type)
{
rwp->rw_type = type;
}
static inline void
spl_rw_lockdep_off_maybe(krwlock_t *rwp) \
{ \
if (rwp && rwp->rw_type == RW_NOLOCKDEP) \
lockdep_off(); \
}
static inline void
spl_rw_lockdep_on_maybe(krwlock_t *rwp) \
{ \
if (rwp && rwp->rw_type == RW_NOLOCKDEP) \
lockdep_on(); \
}
#else /* CONFIG_LOCKDEP */
#define spl_rw_set_type(rwp, type)
#define spl_rw_lockdep_off_maybe(rwp)
#define spl_rw_lockdep_on_maybe(rwp)
#endif /* CONFIG_LOCKDEP */

static inline int
RW_READ_HELD(krwlock_t *rwp)
{
Expand Down Expand Up @@ -110,9 +138,11 @@ RW_LOCK_HELD(krwlock_t *rwp)
#define rw_init(rwp, name, type, arg) \
({ \
static struct lock_class_key __key; \
ASSERT(type == RW_DEFAULT || type == RW_NOLOCKDEP); \
\
__init_rwsem(SEM(rwp), #rwp, &__key); \
spl_rw_clear_owner(rwp); \
spl_rw_set_type(rwp, type); \
})

#define rw_destroy(rwp) \
Expand All @@ -124,6 +154,7 @@ RW_LOCK_HELD(krwlock_t *rwp)
({ \
int _rc_ = 0; \
\
spl_rw_lockdep_off_maybe(rwp); \
switch (rw) { \
case RW_READER: \
_rc_ = down_read_trylock(SEM(rwp)); \
Expand All @@ -135,11 +166,13 @@ RW_LOCK_HELD(krwlock_t *rwp)
default: \
VERIFY(0); \
} \
spl_rw_lockdep_on_maybe(rwp); \
_rc_; \
})

#define rw_enter(rwp, rw) \
({ \
spl_rw_lockdep_off_maybe(rwp); \
switch (rw) { \
case RW_READER: \
down_read(SEM(rwp)); \
Expand All @@ -151,23 +184,28 @@ RW_LOCK_HELD(krwlock_t *rwp)
default: \
VERIFY(0); \
} \
spl_rw_lockdep_on_maybe(rwp); \
})

#define rw_exit(rwp) \
({ \
spl_rw_lockdep_off_maybe(rwp); \
if (RW_WRITE_HELD(rwp)) { \
spl_rw_clear_owner(rwp); \
up_write(SEM(rwp)); \
} else { \
ASSERT(RW_READ_HELD(rwp)); \
up_read(SEM(rwp)); \
} \
spl_rw_lockdep_on_maybe(rwp); \
})

#define rw_downgrade(rwp) \
({ \
spl_rw_lockdep_off_maybe(rwp); \
spl_rw_clear_owner(rwp); \
downgrade_write(SEM(rwp)); \
spl_rw_lockdep_on_maybe(rwp); \
})

#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
Expand All @@ -191,6 +229,7 @@ extern int __down_write_trylock_locked(struct rw_semaphore *);
unsigned long _flags_; \
int _rc_ = 0; \
\
spl_rw_lockdep_off_maybe(rwp); \
spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, _flags_); \
if ((list_empty(&SEM(rwp)->wait_list)) && \
(SEM(rwp)->activity == 1)) { \
Expand All @@ -199,6 +238,7 @@ extern int __down_write_trylock_locked(struct rw_semaphore *);
(rwp)->rw_owner = current; \
} \
spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, _flags_); \
spl_rw_lockdep_on_maybe(rwp); \
_rc_; \
})
#else
Expand Down
9 changes: 9 additions & 0 deletions include/sys/taskq.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@
#define TQ_NEW 0x04000000
#define TQ_FRONT 0x08000000

/* spin_lock(lock) and spin_lock_nested(lock,0) are equivalent,
* so TQ_LOCK_DYNAMIC must not evaluate to 0
*/
typedef enum tq_lock_role {
TQ_LOCK_GENERAL = 0,
TQ_LOCK_DYNAMIC = 1,
} tq_lock_role_t;

typedef unsigned long taskqid_t;
typedef void (task_func_t)(void *);

Expand All @@ -81,6 +89,7 @@ typedef struct taskq {
struct list_head tq_delay_list; /* delayed task_t's */
wait_queue_head_t tq_work_waitq; /* new work waitq */
wait_queue_head_t tq_wait_waitq; /* wait waitq */
tq_lock_role_t tq_lock_class; /* class used when taking tq_lock */
} taskq_t;

typedef struct taskq_ent {
Expand Down
Loading