[OpenAFS-devel] Old problem finally fixed: LINUX deadlock when fstrace active on SMP

Rainer Toebbicke rtb@pclella.cern.ch
Mon, 18 Apr 2005 10:15:57 +0200


This is a multi-part message in MIME format.
--------------060705060803090704090001
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

The delta linux-dentry-deletion-for-unlinked-files-22-version-20020721
and the associated later fix to grab the AFS global lock are in error:

afs_dentry_iput() and afs_dentry_delete() are called under the
dache_lock spinlock.

Obtaining the AFS global lock in those circumstances violates the 
locking hierarchy and leads to a deadlock relatively quickly when more 
than two jobs are accessing AFS (on an SMP).

As it did not occur to me immediately how to fix this reliably, the 
attached patch bluntly disables tracing in that routine for SMP kernels.

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Rainer Toebbicke
European Laboratory for Particle Physics(CERN) - Geneva, Switzerland
Phone: +41 22 767 8985       Fax: +41 22 767 7155

--------------060705060803090704090001
Content-Type: text/plain;
 name="patch_fstrace_deadlock"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch_fstrace_deadlock"

*** openafs/src/afs/LINUX/osi_vnodeops.c.orig1381	2005-03-11 07:51:11.000000000 +0100
--- openafs/src/afs/LINUX/osi_vnodeops.c	2005-04-18 09:33:17.000000000 +0200
***************
*** 931,936 ****
--- 931,937 ----
  static void
  afs_dentry_iput(struct dentry *dp, struct inode *ip)
  {
+ #if !defined(CONFIG_SMP)
      int isglock;
  
      if (ICL_SETACTIVE(afs_iclSetp)) {
***************
*** 941,946 ****
--- 942,948 ----
  		   ICL_TYPE_STRING, dp->d_name.name);
  	if (!isglock) AFS_GUNLOCK();
      }
+ #endif
  
      osi_iput(ip);
  }
***************
*** 949,954 ****
--- 951,957 ----
  static int
  afs_dentry_delete(struct dentry *dp)
  {
+ #if !defined(CONFIG_SMP)
      int isglock;
      if (ICL_SETACTIVE(afs_iclSetp)) {
  	isglock = ISAFS_GLOCK();
***************
*** 958,963 ****
--- 961,967 ----
  		   ICL_TYPE_STRING, dp->d_name.name);
  	if (!isglock) AFS_GUNLOCK();
      }
+ #endif
  
      if (dp->d_inode && (ITOAFS(dp->d_inode)->states & CUnlinked))
  	return 1;		/* bad inode? */

--------------060705060803090704090001--