From: Oleg Drokin Date: Fri, 10 Apr 2015 02:29:20 +0000 (-0400) Subject: LU-6447 mdt: mdt_identity_upcall to not block with rwlock held X-Git-Tag: 2.8.57~46 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=e8273a3dd71c4e6ab5ca9de3fbfbc0f7603d6930;hp=7334a2d33cc4cf4cda0c81b126c4cb8ab28a888d LU-6447 mdt: mdt_identity_upcall to not block with rwlock held mdt_identity_upcall is currently calling call_usermodehelper with an rwlock held, which is a no-no since it allocates memory and schedules. Just replace the rwlock with a rw_semaphore. Change-Id: I7b063a4db47313fbae6241da7bcec2c397b8e8c4 Signed-off-by: Oleg Drokin Signed-off-by: Niu Yawei Reviewed-on: http://review.whamcloud.com/14432 Reviewed-by: Dmitry Eremin Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev --- diff --git a/lustre/include/upcall_cache.h b/lustre/include/upcall_cache.h index 46cfe65..d239a26 100644 --- a/lustre/include/upcall_cache.h +++ b/lustre/include/upcall_cache.h @@ -121,7 +121,7 @@ struct upcall_cache_ops { struct upcall_cache { struct list_head uc_hashtable[UC_CACHE_HASH_SIZE]; spinlock_t uc_lock; - rwlock_t uc_upcall_rwlock; + struct rw_semaphore uc_upcall_rwsem; char uc_name[40]; /* for upcall */ char uc_upcall[UC_CACHE_UPCALL_MAXPATH]; diff --git a/lustre/mdt/mdt_identity.c b/lustre/mdt/mdt_identity.c index 235444c..7d55a0e 100644 --- a/lustre/mdt/mdt_identity.c +++ b/lustre/mdt/mdt_identity.c @@ -113,7 +113,7 @@ static int mdt_identity_do_upcall(struct upcall_cache *cache, /* There is race condition: * "uc_upcall" was changed just after "is_identity_get_disabled" check. */ - read_lock(&cache->uc_upcall_rwlock); + down_read(&cache->uc_upcall_rwsem); CDEBUG(D_INFO, "The upcall is: '%s'\n", cache->uc_upcall); if (unlikely(!strcmp(cache->uc_upcall, "NONE"))) { @@ -141,8 +141,8 @@ static int mdt_identity_do_upcall(struct upcall_cache *cache, } EXIT; out: - read_unlock(&cache->uc_upcall_rwlock); - return rc; + up_read(&cache->uc_upcall_rwsem); + return rc; } static int mdt_identity_parse_downcall(struct upcall_cache *cache, diff --git a/lustre/mdt/mdt_lproc.c b/lustre/mdt/mdt_lproc.c index 38bc9ab..5141394 100644 --- a/lustre/mdt/mdt_lproc.c +++ b/lustre/mdt/mdt_lproc.c @@ -281,9 +281,9 @@ static int mdt_identity_upcall_seq_show(struct seq_file *m, void *data) struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); struct upcall_cache *hash = mdt->mdt_identity_cache; - read_lock(&hash->uc_upcall_rwlock); + down_read(&hash->uc_upcall_rwsem); seq_printf(m, "%s\n", hash->uc_upcall); - read_unlock(&hash->uc_upcall_rwlock); + up_read(&hash->uc_upcall_rwsem); return 0; } @@ -309,9 +309,9 @@ mdt_identity_upcall_seq_write(struct file *file, const char __user *buffer, GOTO(failed, rc = -EFAULT); /* Remove any extraneous bits from the upcall (e.g. linefeeds) */ - write_lock(&hash->uc_upcall_rwlock); + down_write(&hash->uc_upcall_rwsem); sscanf(kernbuf, "%s", hash->uc_upcall); - write_unlock(&hash->uc_upcall_rwlock); + up_write(&hash->uc_upcall_rwsem); if (strcmp(hash->uc_name, mdt_obd_name(mdt)) != 0) CWARN("%s: write to upcall name %s\n", diff --git a/lustre/obdclass/upcall_cache.c b/lustre/obdclass/upcall_cache.c index 165e717..0e350ab 100644 --- a/lustre/obdclass/upcall_cache.c +++ b/lustre/obdclass/upcall_cache.c @@ -428,7 +428,7 @@ struct upcall_cache *upcall_cache_init(const char *name, const char *upcall, RETURN(ERR_PTR(-ENOMEM)); spin_lock_init(&cache->uc_lock); - rwlock_init(&cache->uc_upcall_rwlock); + init_rwsem(&cache->uc_upcall_rwsem); for (i = 0; i < UC_CACHE_HASH_SIZE; i++) INIT_LIST_HEAD(&cache->uc_hashtable[i]); strlcpy(cache->uc_name, name, sizeof(cache->uc_name));