From 89c4e05eb0791665af814a9bbcadf34506d09d40 Mon Sep 17 00:00:00 2001 From: Wang Di Date: Thu, 22 Apr 2010 12:15:24 -0700 Subject: [PATCH] b=22520 set the thread to be uninterrupt before add to waitq In lov_subobject_kill, if the thread needs to wait the object being freed, it should set the thread to be uninterrupt, otherwise, the thread might spin there. i=Eric.mei i=Robert --- lustre/lov/lov_cl_internal.h | 4 ++++ lustre/lov/lov_object.c | 16 +++++++++++++--- lustre/lov/lovsub_object.c | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index 21b0ff4..76cd5e4 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -223,6 +223,10 @@ struct lov_object { */ struct lovsub_object **lo_sub; /** + * protect lo_sub + */ + cfs_spinlock_t lo_sub_lock; + /** * When this is true, lov_object::lo_attr contains * valid up to date attributes for a top-level * object. This field is reset to 0 when attributes of diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 079be23..7b1c458 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -209,6 +209,7 @@ static int lov_init_raid0(const struct lu_env *env, if (r0->lo_sub != NULL) { result = 0; subconf->coc_inode = conf->coc_inode; + cfs_spin_lock_init(&r0->lo_sub_lock); /* * Create stripe cl_objects. */ @@ -264,11 +265,20 @@ static void lov_subobject_kill(const struct lu_env *env, struct lov_object *lov, cfs_waitlink_init(waiter); cfs_waitq_add(&site->ls_marche_funebre, waiter); cfs_set_current_state(CFS_TASK_UNINT); - - while (r0->lo_sub[idx] == los) + while (1) { /* this wait-queue is signaled at the end of * lu_object_free(). */ - cfs_waitq_wait(waiter, CFS_TASK_UNINT); + cfs_set_current_state(CFS_TASK_UNINT); + cfs_spin_lock(&r0->lo_sub_lock); + if (r0->lo_sub[idx] == los) { + cfs_spin_unlock(&r0->lo_sub_lock); + cfs_waitq_wait(waiter, CFS_TASK_UNINT); + } else { + cfs_spin_unlock(&r0->lo_sub_lock); + cfs_set_current_state(CFS_TASK_RUNNING); + break; + } + } cfs_waitq_del(&site->ls_marche_funebre, waiter); } LASSERT(r0->lo_sub[idx] == NULL); diff --git a/lustre/lov/lovsub_object.c b/lustre/lov/lovsub_object.c index 3774df9..d1057f3 100644 --- a/lustre/lov/lovsub_object.c +++ b/lustre/lov/lovsub_object.c @@ -85,7 +85,9 @@ static void lovsub_object_free(const struct lu_env *env, struct lu_object *obj) if (lov) { LASSERT(lov->lo_type == LLT_RAID0); LASSERT(lov->u.raid0.lo_sub[los->lso_index] == los); + cfs_spin_lock(&lov->u.raid0.lo_sub_lock); lov->u.raid0.lo_sub[los->lso_index] = NULL; + cfs_spin_unlock(&lov->u.raid0.lo_sub_lock); } lu_object_fini(obj); -- 1.8.3.1