Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp411559ima; Thu, 31 Jan 2019 19:32:14 -0800 (PST) X-Google-Smtp-Source: AHgI3IbP0/EezOSgYnYUzpmfEljvUjezyS0wQcDOZFzS18FcdO14WvToqx0GWPPOBka0ZorhqaS7 X-Received: by 2002:a65:49c9:: with SMTP id t9mr620278pgs.184.1548991934504; Thu, 31 Jan 2019 19:32:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548991934; cv=none; d=google.com; s=arc-20160816; b=Ulir1a0oY/307IwFJn+zj3cmcVhUsZE5mwbtSA4aUz2z8mc0CPugxbpfXocFg8jrko /q6hrDwZSqslZ4Y2blGc4+xGqIfnmp3eWOXG0UvbD0oD8nLci1Ma1NIgedrf9F0dvwGh PQ+XYPnNCLhP6qww7/f2XIe73+Zs/k/YT2Bp/ujIusE1w/CQxXJRHLPzCL25oDyrH63W +lNzxML+5Bgc7HlG597ZaBXZvtL9h53eMDoqJHSuJxoBBfjv8lzH5lXEhaVeIM/y2k8g BTRiq7To+80R9j4N2gAkXhhTKqSFAgwwq/dQkDYdO4elAMEsyNrkT16ucVoUklXRs4tk KfPQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=/7m4uGxr/GbIiyAtuzOoZgf8Kr1IJ+5N52+KflAz8Z4=; b=jZgaA0K+u7bCZAeysg+Tz6M3lPq/5fXnLrs8CNEmuW4cQH+lPhobSHDvxCtTKkWhA9 2olWDfGNI6MLAilVtU3iYTQFv91wnrPOTKiP0oRnJyKeYiDG3FH6TWkTcvAd112ztwQ3 XZbK8C89iGjsoEnLvLx4v0ZI2sGGFiIiQJGy2e9tbgSWCHFe2dlyd/x3VM4+V26GZBao g9358Pm/wgDv+sU+VvGUXXSQxedAWqobAz0KCt+nwbiM3XX/YlRkwQYQqqXs4glZ6QW1 cUfXyDeW7ZPYE7Aio9sUu6GxguUsm9KzIJH7Iy9ClLZxrxax7sseX1fD0IsfWFcUvcCE oM2w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ucsc.edu header.s=ucsc-google-2018 header.b=OhpGMpE1; 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; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ucsc.edu Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y6si6258010pfi.228.2019.01.31.19.31.59; Thu, 31 Jan 2019 19:32:14 -0800 (PST) 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; dkim=pass header.i=@ucsc.edu header.s=ucsc-google-2018 header.b=OhpGMpE1; 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; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=ucsc.edu Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728074AbfBACie (ORCPT + 99 others); Thu, 31 Jan 2019 21:38:34 -0500 Received: from mail-pg1-f195.google.com ([209.85.215.195]:44794 "EHLO mail-pg1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727313AbfBACid (ORCPT ); Thu, 31 Jan 2019 21:38:33 -0500 Received: by mail-pg1-f195.google.com with SMTP id t13so2214692pgr.11 for ; Thu, 31 Jan 2019 18:38:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucsc.edu; s=ucsc-google-2018; h=from:to:cc:subject:date:message-id; bh=/7m4uGxr/GbIiyAtuzOoZgf8Kr1IJ+5N52+KflAz8Z4=; b=OhpGMpE1J/3BFY4B6562yNrzRauhcjcqgTnbbrh8HYt/tUJw1k3wPJYi32MOosGKHj mGBl9/E5hEVrXVLqjblKNRA7MOXk5zWrskgQLT8J4znPiSF3mA5DNFWY1c/Nwgjq6A84 tS6yip93HVMFEULaT0paHPQ0ylS027qUuFMCDJ5kV2QrcUj0j7RXPmld/OZCsLFqyxzH 0HtBCr61vI+PK30U2yaUChYp9TIEhhOyWyE0NPH34BsnRlrmBZeRS3kxDgEGlxhWALqL YspdTXVxRx5MHPU8jQDiupmL68530SXXWyHLAg00NdFC764rgBPVizkPkPHsRT73t3Uz NvHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=/7m4uGxr/GbIiyAtuzOoZgf8Kr1IJ+5N52+KflAz8Z4=; b=DtvJQImSu6T6HvoIvZiAPsiiiFIF7iFonp8yOpR9FnHVoiWbuuFys2tTo4z3QTjThW euyxnt+rV+K7jwrRQSVF+AiOTic7fOXZEzU/uEe0wj4uUhDvKyeb4Bc8FpjwCV1OiyY9 fuDOtsj2sDZJW9IrvB1ZbBqVEG5x78r7lf4wVG4IyDRksAnXQo7HEmSYAd3SBzCHBWsO Yoh+whZrgLfITrYv1CwO3aFb51vkNZFl2phIah6Z/yRBaLE/TNK8VjonS7zsTcAd/kmH w0k5xmFTzte3BQ+SX5yAmFsz9GrU0z640e65PcTJq1PycVdwMUcJx1QY+hmphpeXpXpf yrGw== X-Gm-Message-State: AJcUukd/B7B19eAtGbJL/RdHfcFUP6L0N9rKXs9dm0UO/vJWq9uUVju8 xj8xm/hTCEVRYo0sLqj+pPW81Q== X-Received: by 2002:a62:3888:: with SMTP id f130mr36616644pfa.132.1548988712415; Thu, 31 Jan 2019 18:38:32 -0800 (PST) Received: from bohr1.soe.ucsc.edu (bohr1.soe.ucsc.edu. [128.114.52.184]) by smtp.gmail.com with ESMTPSA id y9sm9709459pfi.74.2019.01.31.18.38.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 31 Jan 2019 18:38:30 -0800 (PST) From: Heiner Litz To: mb@lightnvm.io Cc: javier@javigon.com, hans.holmberg@cnexlabs.com, linux-block@vger.kernel.org, linux-kernel@vger.kernel.org, Heiner Litz Subject: [PATCH V2] lightnvm: pblk: fix race condition on GC Date: Thu, 31 Jan 2019 18:38:06 -0800 Message-Id: <20190201023806.39895-1-hlitz@ucsc.edu> X-Mailer: git-send-email 2.17.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch fixes a race condition where a write is mapped to the last sectors of a line. The write is synced to the device but the L2P is not updated yet. When the line is garbage collected before the L2P update is performed, the sectors are ignored by the GC logic and the line is freed before all sectors are moved. When the L2P is finally updated, it contains a mapping to a freed line, subsequent reads of the corresponding LBAs fail. This patch introduces a per line counter specifying the number of sectors that are synced to the device but have not been updated in the L2P. Lines with a counter of greater than zero will not be selected for GC. Signed-off-by: Heiner Litz --- v2: changed according to Javier's comment. Instead of performing check while holding the trans_lock, add an atomic per line counter drivers/lightnvm/pblk-core.c | 1 + drivers/lightnvm/pblk-gc.c | 20 +++++++++++++------- drivers/lightnvm/pblk-map.c | 1 + drivers/lightnvm/pblk-rb.c | 1 + drivers/lightnvm/pblk-write.c | 1 + drivers/lightnvm/pblk.h | 1 + 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c index eabcbc119681..b7ed0502abef 100644 --- a/drivers/lightnvm/pblk-core.c +++ b/drivers/lightnvm/pblk-core.c @@ -1278,6 +1278,7 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line) spin_unlock(&line->lock); kref_init(&line->ref); + atomic_set(&line->sec_to_update, 0); return 0; } diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c index 2fa118c8eb71..26a52ea7ec45 100644 --- a/drivers/lightnvm/pblk-gc.c +++ b/drivers/lightnvm/pblk-gc.c @@ -365,16 +365,22 @@ static struct pblk_line *pblk_gc_get_victim_line(struct pblk *pblk, struct list_head *group_list) { struct pblk_line *line, *victim; - int line_vsc, victim_vsc; + unsigned int line_vsc = ~0x0L, victim_vsc = ~0x0L; victim = list_first_entry(group_list, struct pblk_line, list); + list_for_each_entry(line, group_list, list) { - line_vsc = le32_to_cpu(*line->vsc); - victim_vsc = le32_to_cpu(*victim->vsc); - if (line_vsc < victim_vsc) + if (!atomic_read(&line->sec_to_update)) + line_vsc = le32_to_cpu(*line->vsc); + if (line_vsc < victim_vsc) { victim = line; + victim_vsc = le32_to_cpu(*victim->vsc); + } } + if (victim_vsc == ~0x0) + return NULL; + return victim; } @@ -448,13 +454,13 @@ static void pblk_gc_run(struct pblk *pblk) do { spin_lock(&l_mg->gc_lock); - if (list_empty(group_list)) { + + line = pblk_gc_get_victim_line(pblk, group_list); + if (!line) { spin_unlock(&l_mg->gc_lock); break; } - line = pblk_gc_get_victim_line(pblk, group_list); - spin_lock(&line->lock); WARN_ON(line->state != PBLK_LINESTATE_CLOSED); line->state = PBLK_LINESTATE_GC; diff --git a/drivers/lightnvm/pblk-map.c b/drivers/lightnvm/pblk-map.c index 79df583ea709..7fbc99b60cac 100644 --- a/drivers/lightnvm/pblk-map.c +++ b/drivers/lightnvm/pblk-map.c @@ -73,6 +73,7 @@ static int pblk_map_page_data(struct pblk *pblk, unsigned int sentry, */ if (i < valid_secs) { kref_get(&line->ref); + atomic_inc(&line->sec_to_update); w_ctx = pblk_rb_w_ctx(&pblk->rwb, sentry + i); w_ctx->ppa = ppa_list[i]; meta->lba = cpu_to_le64(w_ctx->lba); diff --git a/drivers/lightnvm/pblk-rb.c b/drivers/lightnvm/pblk-rb.c index a6133b50ed9c..03c241b340ea 100644 --- a/drivers/lightnvm/pblk-rb.c +++ b/drivers/lightnvm/pblk-rb.c @@ -260,6 +260,7 @@ static int __pblk_rb_update_l2p(struct pblk_rb *rb, unsigned int to_update) entry->cacheline); line = pblk_ppa_to_line(pblk, w_ctx->ppa); + atomic_dec(&line->sec_to_update); kref_put(&line->ref, pblk_line_put); clean_wctx(w_ctx); rb->l2p_update = pblk_rb_ptr_wrap(rb, rb->l2p_update, 1); diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c index 06d56deb645d..6593deab52da 100644 --- a/drivers/lightnvm/pblk-write.c +++ b/drivers/lightnvm/pblk-write.c @@ -177,6 +177,7 @@ static void pblk_prepare_resubmit(struct pblk *pblk, unsigned int sentry, * re-map these entries */ line = pblk_ppa_to_line(pblk, w_ctx->ppa); + atomic_dec(&line->sec_to_update); kref_put(&line->ref, pblk_line_put); } spin_unlock(&pblk->trans_lock); diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h index a6386d5acd73..ac3ab778e976 100644 --- a/drivers/lightnvm/pblk.h +++ b/drivers/lightnvm/pblk.h @@ -487,6 +487,7 @@ struct pblk_line { __le32 *vsc; /* Valid sector count in line */ struct kref ref; /* Write buffer L2P references */ + atomic_t sec_to_update; /* Outstanding L2P updates to ppa */ struct pblk_w_err_gc *w_err_gc; /* Write error gc recovery metadata */ -- 2.17.1