Received: by 10.192.165.148 with SMTP id m20csp4497673imm; Mon, 30 Apr 2018 20:54:04 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrLi/q9T3yvr/YJ72RpDl1qBIsaKpPKsc2WgikEAC6yZzKHtPFEF+1xoLwaaQHicwfBYg72 X-Received: by 2002:a17:902:ab93:: with SMTP id f19-v6mr13849131plr.392.1525146844089; Mon, 30 Apr 2018 20:54:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525146844; cv=none; d=google.com; s=arc-20160816; b=TY1hwJDwH1oPYRdSj5IH6AGsV+dB0NJ8TjvJQzylYW9IsD+uE1bhdG3XkPzcescMDz VCnpfvlnhJwt0i9Ch48BLS8G7yHZxmazzpuF+qzii8I2RgxeCDQ4PqIydScnGC1JLucG lyJFaMBQA4uLaI8HBnWFFLwbyW7R3BJRVYGwapAVSBBn3o0J4zaUBxz/EMYP4ZnkvsTY kPhasodhKLYRHUqdLzWtH2cmn/c1Hxc7iLjV7EkWuIjajcRzUGthiXwyIZFnmMgPjPk2 w05mH+WIDQBWAMdCCU5SFyaexc/yYEF5mzb6eLch27njKLzfvynS7NEK6Zp3xFufpvym 5GOw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:cc:subject:date:to :from:arc-authentication-results; bh=BtOYFDE5mqZysnSSWYo+8LSAUNHEZN1iubJY4vWLekM=; b=zSwZ0A4SfAe1bEsNBjIa+BewOkDV04n6IX9/Wo+AVe5SZkgI8HY3o6gZpOFZO7T3G3 BKzASAuwfngZVIeq2jqOtyQwHr1LJl6bY2+x6I1ubga59BLQqU6s4VbLeIsv+dQSqfrH vgs7OROMyhbBCGCmIHLhhOT1/d2KqO3xOSBOHvd5HKtpdphodvzxPwcgWWTHR+5dvChv Y7JLUyFexftYQUyS3qz+Cyr7BMy6UcznveHe08kDtDyeYo48Gj9zlZvL5i81OwBrS/Pg 9373WCOHJIDxiZLuOZRmO/GHqrBhSqFAICYOOmwcFYO47LjAVsLvzqoMyTgRnWi09nxo YXzg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u15si9069835pfk.82.2018.04.30.20.53.50; Mon, 30 Apr 2018 20:54:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755194AbeEADxc (ORCPT + 99 others); Mon, 30 Apr 2018 23:53:32 -0400 Received: from mx2.suse.de ([195.135.220.15]:59183 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755151AbeEADxa (ORCPT ); Mon, 30 Apr 2018 23:53:30 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C369EAE54; Tue, 1 May 2018 03:53:28 +0000 (UTC) From: NeilBrown To: Oleg Drokin , Greg Kroah-Hartman , James Simmons , Andreas Dilger Date: Tue, 01 May 2018 13:52:39 +1000 Subject: [PATCH 04/10] staging: lustre: lu_object: move retry logic inside htable_lookup Cc: Linux Kernel Mailing List , Lustre Development List Message-ID: <152514675897.17843.15112214060540196720.stgit@noble> In-Reply-To: <152514658325.17843.11455067361317157487.stgit@noble> References: <152514658325.17843.11455067361317157487.stgit@noble> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The current retry logic, to wait when a 'dying' object is found, spans multiple functions. The process is attached to a waitqueue and set TASK_UNINTERRUPTIBLE in htable_lookup, and this status is passed back through lu_object_find_try() to lu_object_find_at() where schedule() is called and the process is removed from the queue. This can be simplified by moving all the logic (including hashtable locking) inside htable_lookup(), which now never returns EAGAIN. Note that htable_lookup() is called with the hash bucket lock held, and will drop and retake it if it needs to schedule. I made this a 'goto' loop rather than a 'while(1)' loop as the diff is easier to read. Signed-off-by: NeilBrown --- drivers/staging/lustre/lustre/obdclass/lu_object.c | 73 +++++++------------- 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/lu_object.c b/drivers/staging/lustre/lustre/obdclass/lu_object.c index 2bf089817157..93daa52e2535 100644 --- a/drivers/staging/lustre/lustre/obdclass/lu_object.c +++ b/drivers/staging/lustre/lustre/obdclass/lu_object.c @@ -586,16 +586,21 @@ EXPORT_SYMBOL(lu_object_print); static struct lu_object *htable_lookup(struct lu_site *s, struct cfs_hash_bd *bd, const struct lu_fid *f, - wait_queue_entry_t *waiter, __u64 *version) { + struct cfs_hash *hs = s->ls_obj_hash; struct lu_site_bkt_data *bkt; struct lu_object_header *h; struct hlist_node *hnode; - __u64 ver = cfs_hash_bd_version_get(bd); + __u64 ver; + wait_queue_entry_t waiter; - if (*version == ver) +retry: + ver = cfs_hash_bd_version_get(bd); + + if (*version == ver) { return ERR_PTR(-ENOENT); + } *version = ver; bkt = cfs_hash_bd_extra_get(s->ls_obj_hash, bd); @@ -625,11 +630,15 @@ static struct lu_object *htable_lookup(struct lu_site *s, * drained), and moreover, lookup has to wait until object is freed. */ - init_waitqueue_entry(waiter, current); - add_wait_queue(&bkt->lsb_marche_funebre, waiter); + init_waitqueue_entry(&waiter, current); + add_wait_queue(&bkt->lsb_marche_funebre, &waiter); set_current_state(TASK_UNINTERRUPTIBLE); lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_DEATH_RACE); - return ERR_PTR(-EAGAIN); + cfs_hash_bd_unlock(hs, bd, 1); + schedule(); + remove_wait_queue(&bkt->lsb_marche_funebre, &waiter); + cfs_hash_bd_lock(hs, bd, 1); + goto retry; } /** @@ -693,13 +702,14 @@ static struct lu_object *lu_object_new(const struct lu_env *env, } /** - * Core logic of lu_object_find*() functions. + * Much like lu_object_find(), but top level device of object is specifically + * \a dev rather than top level device of the site. This interface allows + * objects of different "stacking" to be created within the same site. */ -static struct lu_object *lu_object_find_try(const struct lu_env *env, - struct lu_device *dev, - const struct lu_fid *f, - const struct lu_object_conf *conf, - wait_queue_entry_t *waiter) +struct lu_object *lu_object_find_at(const struct lu_env *env, + struct lu_device *dev, + const struct lu_fid *f, + const struct lu_object_conf *conf) { struct lu_object *o; struct lu_object *shadow; @@ -725,17 +735,16 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env, * It is unnecessary to perform lookup-alloc-lookup-insert, instead, * just alloc and insert directly. * - * If dying object is found during index search, add @waiter to the - * site wait-queue and return ERR_PTR(-EAGAIN). */ if (conf && conf->loc_flags & LOC_F_NEW) return lu_object_new(env, dev, f, conf); s = dev->ld_site; hs = s->ls_obj_hash; - cfs_hash_bd_get_and_lock(hs, (void *)f, &bd, 1); - o = htable_lookup(s, &bd, f, waiter, &version); - cfs_hash_bd_unlock(hs, &bd, 1); + cfs_hash_bd_get_and_lock(hs, (void *)f, &bd, 0); + o = htable_lookup(s, &bd, f, &version); + cfs_hash_bd_unlock(hs, &bd, 0); + if (!IS_ERR(o) || PTR_ERR(o) != -ENOENT) return o; @@ -751,7 +760,7 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env, cfs_hash_bd_lock(hs, &bd, 1); - shadow = htable_lookup(s, &bd, f, waiter, &version); + shadow = htable_lookup(s, &bd, f, &version); if (likely(PTR_ERR(shadow) == -ENOENT)) { cfs_hash_bd_add_locked(hs, &bd, &o->lo_header->loh_hash); cfs_hash_bd_unlock(hs, &bd, 1); @@ -766,34 +775,6 @@ static struct lu_object *lu_object_find_try(const struct lu_env *env, lu_object_free(env, o); return shadow; } - -/** - * Much like lu_object_find(), but top level device of object is specifically - * \a dev rather than top level device of the site. This interface allows - * objects of different "stacking" to be created within the same site. - */ -struct lu_object *lu_object_find_at(const struct lu_env *env, - struct lu_device *dev, - const struct lu_fid *f, - const struct lu_object_conf *conf) -{ - wait_queue_head_t *wq; - struct lu_object *obj; - wait_queue_entry_t wait; - - while (1) { - obj = lu_object_find_try(env, dev, f, conf, &wait); - if (obj != ERR_PTR(-EAGAIN)) - return obj; - /* - * lu_object_find_try() already added waiter into the - * wait queue. - */ - schedule(); - wq = lu_site_wq_from_fid(dev->ld_site, (void *)f); - remove_wait_queue(wq, &wait); - } -} EXPORT_SYMBOL(lu_object_find_at); /**