[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--