mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Remove misguided HAVE_MUTEX_OWNER check, take 2
It is just plain unsafe to peek inside in-kernel
mutex structure and make assumptions about what kernel
does with those internal fields like owner.
Kernel is all too happy to stop doing the expected things
like tracing lock owner once you load a tainted module
like spl/zfs that is not GPL.
As such you will get instant assertion failures like this:
  VERIFY3(((*(volatile typeof((&((&zo->zo_lock)->m_mutex))->owner) *)&
      ((&((&zo->zo_lock)->m_mutex))->owner))) ==
     ((void *)0)) failed (ffff88030be28500 == (null))
  PANIC at zfs_onexit.c:104:zfs_onexit_destroy()
  Showing stack for process 3626
  CPU: 0 PID: 3626 Comm: mkfs.lustre Tainted: P OE ------------ 3.10.0-debug #1
  Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
  Call Trace:
  dump_stack+0x19/0x1b
  spl_dumpstack+0x44/0x50 [spl]
  spl_panic+0xbf/0xf0 [spl]
  zfs_onexit_destroy+0x17c/0x280 [zfs]
  zfsdev_release+0x48/0xd0 [zfs]
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Chunwei Chen <david.chen@osnexus.com>
Reviewed-by: Gvozden Neskovic <neskovic@gmail.com>
Signed-off-by: Oleg Drokin <green@linuxhacker.ru>
Closes #639
Closes #632
			
			
This commit is contained in:
		
							parent
							
								
									261a3151e1
								
							
						
					
					
						commit
						98cdcb8286
					
				| @ -49,7 +49,6 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ | |||||||
| 	SPL_AC_USLEEP_RANGE | 	SPL_AC_USLEEP_RANGE | ||||||
| 	SPL_AC_KMEM_CACHE_ALLOCFLAGS | 	SPL_AC_KMEM_CACHE_ALLOCFLAGS | ||||||
| 	SPL_AC_WAIT_ON_BIT | 	SPL_AC_WAIT_ON_BIT | ||||||
| 	SPL_AC_MUTEX_OWNER |  | ||||||
| 	SPL_AC_INODE_LOCK | 	SPL_AC_INODE_LOCK | ||||||
| 	SPL_AC_GROUP_INFO_GID | 	SPL_AC_GROUP_INFO_GID | ||||||
| 	SPL_AC_KMEM_CACHE_CREATE_USERCOPY | 	SPL_AC_KMEM_CACHE_CREATE_USERCOPY | ||||||
| @ -1562,35 +1561,6 @@ AC_DEFUN([SPL_AC_WAIT_ON_BIT], [ | |||||||
| 	]) | 	]) | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
| dnl # |  | ||||||
| dnl # Check whether mutex has owner with task_struct type. |  | ||||||
| dnl # |  | ||||||
| dnl # Note that before Linux 3.0, mutex owner is of type thread_info. |  | ||||||
| dnl # |  | ||||||
| dnl # Note that in Linux 3.18, the condition for owner is changed from |  | ||||||
| dnl # defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) to |  | ||||||
| dnl # defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER) |  | ||||||
| dnl # |  | ||||||
| AC_DEFUN([SPL_AC_MUTEX_OWNER], [ |  | ||||||
| 	AC_MSG_CHECKING([whether mutex has owner]) |  | ||||||
| 	tmp_flags="$EXTRA_KCFLAGS" |  | ||||||
| 	EXTRA_KCFLAGS="-Werror" |  | ||||||
| 	SPL_LINUX_TRY_COMPILE([ |  | ||||||
| 		#include <linux/mutex.h> |  | ||||||
| 		#include <linux/spinlock.h> |  | ||||||
| 	],[ |  | ||||||
| 		DEFINE_MUTEX(m); |  | ||||||
| 		struct task_struct *t __attribute__ ((unused)); |  | ||||||
| 		t = m.owner; |  | ||||||
| 	],[ |  | ||||||
| 		AC_MSG_RESULT(yes) |  | ||||||
| 		AC_DEFINE(HAVE_MUTEX_OWNER, 1, [yes]) |  | ||||||
| 	],[ |  | ||||||
| 		AC_MSG_RESULT(no) |  | ||||||
| 	]) |  | ||||||
| 	EXTRA_KCFLAGS="$tmp_flags" |  | ||||||
| ]) |  | ||||||
| 
 |  | ||||||
| dnl # | dnl # | ||||||
| dnl # 4.7 API change | dnl # 4.7 API change | ||||||
| dnl # i_mutex is changed to i_rwsem. Instead of directly using | dnl # i_mutex is changed to i_rwsem. Instead of directly using | ||||||
|  | |||||||
| @ -40,10 +40,7 @@ typedef enum { | |||||||
| typedef struct { | typedef struct { | ||||||
| 	struct mutex		m_mutex; | 	struct mutex		m_mutex; | ||||||
| 	spinlock_t		m_lock;	/* used for serializing mutex_exit */ | 	spinlock_t		m_lock;	/* used for serializing mutex_exit */ | ||||||
| #ifndef HAVE_MUTEX_OWNER |  | ||||||
| 	/* only when kernel doesn't have owner */ |  | ||||||
| 	kthread_t		*m_owner; | 	kthread_t		*m_owner; | ||||||
| #endif |  | ||||||
| #ifdef CONFIG_LOCKDEP | #ifdef CONFIG_LOCKDEP | ||||||
| 	kmutex_type_t		m_type; | 	kmutex_type_t		m_type; | ||||||
| #endif /* CONFIG_LOCKDEP */ | #endif /* CONFIG_LOCKDEP */ | ||||||
| @ -54,28 +51,16 @@ typedef struct { | |||||||
| static inline void | static inline void | ||||||
| spl_mutex_set_owner(kmutex_t *mp) | spl_mutex_set_owner(kmutex_t *mp) | ||||||
| { | { | ||||||
| 	/*
 |  | ||||||
| 	 * kernel will handle its owner, so we don't need to do anything if it |  | ||||||
| 	 * is defined. |  | ||||||
| 	 */ |  | ||||||
| #ifndef HAVE_MUTEX_OWNER |  | ||||||
| 	mp->m_owner = current; | 	mp->m_owner = current; | ||||||
| #endif |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline void | static inline void | ||||||
| spl_mutex_clear_owner(kmutex_t *mp) | spl_mutex_clear_owner(kmutex_t *mp) | ||||||
| { | { | ||||||
| #ifndef HAVE_MUTEX_OWNER |  | ||||||
| 	mp->m_owner = NULL; | 	mp->m_owner = NULL; | ||||||
| #endif |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef HAVE_MUTEX_OWNER |  | ||||||
| #define	mutex_owner(mp)		(ACCESS_ONCE(MUTEX(mp)->owner)) |  | ||||||
| #else |  | ||||||
| #define	mutex_owner(mp)		(ACCESS_ONCE((mp)->m_owner)) | #define	mutex_owner(mp)		(ACCESS_ONCE((mp)->m_owner)) | ||||||
| #endif |  | ||||||
| #define	mutex_owned(mp)		(mutex_owner(mp) == current) | #define	mutex_owned(mp)		(mutex_owner(mp) == current) | ||||||
| #define	MUTEX_HELD(mp)		mutex_owned(mp) | #define	MUTEX_HELD(mp)		mutex_owned(mp) | ||||||
| #define	MUTEX_NOT_HELD(mp)	(!MUTEX_HELD(mp)) | #define	MUTEX_NOT_HELD(mp)	(!MUTEX_HELD(mp)) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Oleg Drokin
						Oleg Drokin