Skip to content

Commit

Permalink
Merge tag 'libnvdimm-fixes-for-5.12-rc8' of git://git.kernel.org/pub/…
Browse files Browse the repository at this point in the history
…scm/linux/kernel/git/nvdimm/nvdimm

Pull libnvdimm fixes from Dan Williams:
 "The largest change is for a regression that landed during -rc1 for
  block-device read-only handling. Vaibhav found a new use for the
  ability (originally introduced by virtio_pmem) to call back to the
  platform to flush data, but also found an original bug in that
  implementation. Lastly, Arnd cleans up some compile warnings in dax.

  This has all appeared in -next with no reported issues.

  Summary:

   - Fix a regression of read-only handling in the pmem driver

   - Fix a compile warning

   - Fix support for platform cache flush commands on powerpc/papr"

* tag 'libnvdimm-fixes-for-5.12-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  libnvdimm/region: Fix nvdimm_has_flush() to handle ND_REGION_ASYNC
  libnvdimm: Notify disk drivers to revalidate region read-only
  dax: avoid -Wempty-body warnings
  • Loading branch information
torvalds committed Apr 17, 2021
2 parents 7c22677 + 11d2498 commit bdfd99e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 18 deletions.
6 changes: 2 additions & 4 deletions drivers/dax/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,11 @@ static ssize_t do_id_store(struct device_driver *drv, const char *buf,
list_add(&dax_id->list, &dax_drv->ids);
} else
rc = -ENOMEM;
} else
/* nothing to remove */;
}
} else if (action == ID_REMOVE) {
list_del(&dax_id->list);
kfree(dax_id);
} else
/* dax_id already added */;
}
mutex_unlock(&dax_bus_lock);

if (rc < 0)
Expand Down
14 changes: 6 additions & 8 deletions drivers/nvdimm/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,16 +631,14 @@ void nvdimm_check_and_set_ro(struct gendisk *disk)
struct nd_region *nd_region = to_nd_region(dev->parent);
int disk_ro = get_disk_ro(disk);

/*
* Upgrade to read-only if the region is read-only preserve as
* read-only if the disk is already read-only.
*/
if (disk_ro || nd_region->ro == disk_ro)
/* catch the disk up with the region ro state */
if (disk_ro == nd_region->ro)
return;

dev_info(dev, "%s read-only, marking %s read-only\n",
dev_name(&nd_region->dev), disk->disk_name);
set_disk_ro(disk, 1);
dev_info(dev, "%s read-%s, marking %s read-%s\n",
dev_name(&nd_region->dev), nd_region->ro ? "only" : "write",
disk->disk_name, nd_region->ro ? "only" : "write");
set_disk_ro(disk, nd_region->ro);
}
EXPORT_SYMBOL(nvdimm_check_and_set_ro);

Expand Down
37 changes: 33 additions & 4 deletions drivers/nvdimm/pmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/mm.h>
#include <asm/cacheflush.h>
#include "pmem.h"
#include "btt.h"
#include "pfn.h"
#include "nd.h"

Expand Down Expand Up @@ -585,7 +586,7 @@ static void nd_pmem_shutdown(struct device *dev)
nvdimm_flush(to_nd_region(dev->parent), NULL);
}

static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
static void pmem_revalidate_poison(struct device *dev)
{
struct nd_region *nd_region;
resource_size_t offset = 0, end_trunc = 0;
Expand All @@ -595,9 +596,6 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
struct range range;
struct kernfs_node *bb_state;

if (event != NVDIMM_REVALIDATE_POISON)
return;

if (is_nd_btt(dev)) {
struct nd_btt *nd_btt = to_nd_btt(dev);

Expand Down Expand Up @@ -635,6 +633,37 @@ static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
sysfs_notify_dirent(bb_state);
}

static void pmem_revalidate_region(struct device *dev)
{
struct pmem_device *pmem;

if (is_nd_btt(dev)) {
struct nd_btt *nd_btt = to_nd_btt(dev);
struct btt *btt = nd_btt->btt;

nvdimm_check_and_set_ro(btt->btt_disk);
return;
}

pmem = dev_get_drvdata(dev);
nvdimm_check_and_set_ro(pmem->disk);
}

static void nd_pmem_notify(struct device *dev, enum nvdimm_event event)
{
switch (event) {
case NVDIMM_REVALIDATE_POISON:
pmem_revalidate_poison(dev);
break;
case NVDIMM_REVALIDATE_REGION:
pmem_revalidate_region(dev);
break;
default:
dev_WARN_ONCE(dev, 1, "notify: unknown event: %d\n", event);
break;
}
}

MODULE_ALIAS("pmem");
MODULE_ALIAS_ND_DEVICE(ND_DEVICE_NAMESPACE_IO);
MODULE_ALIAS_ND_DEVICE(ND_DEVICE_NAMESPACE_PMEM);
Expand Down
16 changes: 14 additions & 2 deletions drivers/nvdimm/region_devs.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,12 @@ static ssize_t read_only_show(struct device *dev,
return sprintf(buf, "%d\n", nd_region->ro);
}

static int revalidate_read_only(struct device *dev, void *data)
{
nd_device_notify(dev, NVDIMM_REVALIDATE_REGION);
return 0;
}

static ssize_t read_only_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t len)
{
Expand All @@ -529,6 +535,7 @@ static ssize_t read_only_store(struct device *dev,
return rc;

nd_region->ro = ro;
device_for_each_child(dev, NULL, revalidate_read_only);
return len;
}
static DEVICE_ATTR_RW(read_only);
Expand Down Expand Up @@ -1239,6 +1246,11 @@ int nvdimm_has_flush(struct nd_region *nd_region)
|| !IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API))
return -ENXIO;

/* Test if an explicit flush function is defined */
if (test_bit(ND_REGION_ASYNC, &nd_region->flags) && nd_region->flush)
return 1;

/* Test if any flush hints for the region are available */
for (i = 0; i < nd_region->ndr_mappings; i++) {
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
struct nvdimm *nvdimm = nd_mapping->nvdimm;
Expand All @@ -1249,8 +1261,8 @@ int nvdimm_has_flush(struct nd_region *nd_region)
}

/*
* The platform defines dimm devices without hints, assume
* platform persistence mechanism like ADR
* The platform defines dimm devices without hints nor explicit flush,
* assume platform persistence mechanism like ADR
*/
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions include/linux/nd.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

enum nvdimm_event {
NVDIMM_REVALIDATE_POISON,
NVDIMM_REVALIDATE_REGION,
};

enum nvdimm_claim_class {
Expand Down

0 comments on commit bdfd99e

Please sign in to comment.