Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933132AbcCKAkF (ORCPT ); Thu, 10 Mar 2016 19:40:05 -0500 Received: from mga11.intel.com ([192.55.52.93]:62953 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932893AbcCKAkC (ORCPT ); Thu, 10 Mar 2016 19:40:02 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,318,1455004800"; d="scan'208";a="762035747" From: "Verma, Vishal L" To: "Williams, Dan J" , "linux-nvdimm@lists.01.org" CC: "ross.zwisler@linux.intel.com" , "linux-kernel@vger.kernel.org" , "x86@kernel.org" , "linux-acpi@vger.kernel.org" Subject: Re: [PATCH 3/3] libnvdimm, pmem: clear poison on write Thread-Topic: [PATCH 3/3] libnvdimm, pmem: clear poison on write Thread-Index: AQHReYySHa6UJRu1TU6XNch1PXK5uZ9T8AKA Date: Fri, 11 Mar 2016 00:39:45 +0000 Message-ID: <1457656781.4525.36.camel@intel.com> References: <20160308224713.16298.33547.stgit@dwillia2-desk3.jf.intel.com> <20160308224729.16298.49406.stgit@dwillia2-desk3.jf.intel.com> In-Reply-To: <20160308224729.16298.49406.stgit@dwillia2-desk3.jf.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.232.112.171] Content-Type: text/plain; charset="utf-8" Content-ID: <351DA761BDF12A459E1C5C6CC10AAAA3@intel.com> MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from base64 to 8bit by mail.home.local id u2B0eMq2011894 Content-Length: 2182 Lines: 68 On Tue, 2016-03-08 at 14:47 -0800, Dan Williams wrote: > If a write is directed at a known bad block perform the following: > > 1/ write the data > > 2/ send a clear poison command > > 3/ invalidate the poison out of the cache hierarchy > > Cc: > Cc: Vishal Verma > Cc: Ross Zwisler > Signed-off-by: Dan Williams > --- >  arch/x86/include/asm/pmem.h |    5 +++++ >  drivers/nvdimm/bus.c        |   46 > +++++++++++++++++++++++++++++++++++++++++++ >  drivers/nvdimm/nd.h         |    2 ++ >  drivers/nvdimm/pmem.c       |   29 ++++++++++++++++++++++++++- >  include/linux/pmem.h        |   19 ++++++++++++++++++ >  5 files changed, 100 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h > index c57fd1ea9689..bf8b35d2035a 100644 > --- a/arch/x86/include/asm/pmem.h > +++ b/arch/x86/include/asm/pmem.h <> >  static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, >   unsigned int len, unsigned int off, int rw, >   sector_t sector) >  { >   int rc = 0; > + bool bad_pmem = false; >   void *mem = kmap_atomic(page); >   phys_addr_t pmem_off = sector * 512 + pmem->data_offset; >   void __pmem *pmem_addr = pmem->virt_addr + pmem_off; >   > + if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) > + bad_pmem = true; > + >   if (rw == READ) { > - if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) > + if (unlikely(bad_pmem)) >   rc = -EIO; >   else { >   memcpy_from_pmem(mem + off, pmem_addr, len); > @@ -81,6 +104,10 @@ static int pmem_do_bvec(struct pmem_device *pmem, > struct page *page, >   } else { >   flush_dcache_page(page); >   memcpy_to_pmem(pmem_addr, mem + off, len); > + if (unlikely(bad_pmem)) { > + pmem_clear_poison(pmem, pmem_off, len); > + memcpy_to_pmem(pmem_addr, mem + off, len); > + } >   } Just noticed this -- why do we memcpy_to_pmem twice in the error case? Sh ouldn't it be: if (unlikely(bad_pmem)) pmem_clear_poison(pmem, pmem_off, len); memcpy_to_pmem(pmem_addr, mem + off, len);