mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'for-4.10/libnvdimm' into libnvdimm-for-next
This commit is contained in:
commit
c44ef859ce
14 changed files with 190 additions and 80 deletions
|
|
@ -22,9 +22,8 @@ void __nd_detach_ndns(struct device *dev, struct nd_namespace_common **_ndns)
|
|||
{
|
||||
struct nd_namespace_common *ndns = *_ndns;
|
||||
|
||||
dev_WARN_ONCE(dev, !mutex_is_locked(&ndns->dev.mutex)
|
||||
|| ndns->claim != dev,
|
||||
"%s: invalid claim\n", __func__);
|
||||
lockdep_assert_held(&ndns->dev.mutex);
|
||||
dev_WARN_ONCE(dev, ndns->claim != dev, "%s: invalid claim\n", __func__);
|
||||
ndns->claim = NULL;
|
||||
*_ndns = NULL;
|
||||
put_device(&ndns->dev);
|
||||
|
|
@ -49,9 +48,8 @@ bool __nd_attach_ndns(struct device *dev, struct nd_namespace_common *attach,
|
|||
{
|
||||
if (attach->claim)
|
||||
return false;
|
||||
dev_WARN_ONCE(dev, !mutex_is_locked(&attach->dev.mutex)
|
||||
|| *_ndns,
|
||||
"%s: invalid claim\n", __func__);
|
||||
lockdep_assert_held(&attach->dev.mutex);
|
||||
dev_WARN_ONCE(dev, *_ndns, "%s: invalid claim\n", __func__);
|
||||
attach->claim = dev;
|
||||
*_ndns = attach;
|
||||
get_device(&attach->dev);
|
||||
|
|
@ -226,6 +224,12 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
|
|||
resource_size_t offset, void *buf, size_t size, int rw)
|
||||
{
|
||||
struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
|
||||
unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
|
||||
sector_t sector = offset >> 9;
|
||||
int rc = 0;
|
||||
|
||||
if (unlikely(!size))
|
||||
return 0;
|
||||
|
||||
if (unlikely(offset + size > nsio->size)) {
|
||||
dev_WARN_ONCE(&ndns->dev, 1, "request out of range\n");
|
||||
|
|
@ -233,17 +237,31 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
|
|||
}
|
||||
|
||||
if (rw == READ) {
|
||||
unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
|
||||
|
||||
if (unlikely(is_bad_pmem(&nsio->bb, offset / 512, sz_align)))
|
||||
if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align)))
|
||||
return -EIO;
|
||||
return memcpy_from_pmem(buf, nsio->addr + offset, size);
|
||||
} else {
|
||||
memcpy_to_pmem(nsio->addr + offset, buf, size);
|
||||
nvdimm_flush(to_nd_region(ndns->dev.parent));
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align))) {
|
||||
if (IS_ALIGNED(offset, 512) && IS_ALIGNED(size, 512)) {
|
||||
long cleared;
|
||||
|
||||
cleared = nvdimm_clear_poison(&ndns->dev, offset, size);
|
||||
if (cleared < size)
|
||||
rc = -EIO;
|
||||
if (cleared > 0 && cleared / 512) {
|
||||
cleared /= 512;
|
||||
badblocks_clear(&nsio->bb, sector, cleared);
|
||||
}
|
||||
invalidate_pmem(nsio->addr + offset, size);
|
||||
} else
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
memcpy_to_pmem(nsio->addr + offset, buf, size);
|
||||
nvdimm_flush(to_nd_region(ndns->dev.parent));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio)
|
||||
|
|
@ -253,7 +271,7 @@ int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio)
|
|||
|
||||
nsio->size = resource_size(res);
|
||||
if (!devm_request_mem_region(dev, res->start, resource_size(res),
|
||||
dev_name(dev))) {
|
||||
dev_name(&ndns->dev))) {
|
||||
dev_warn(dev, "could not reserve region %pR\n", res);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,35 +317,6 @@ ssize_t nd_sector_size_store(struct device *dev, const char *buf,
|
|||
}
|
||||
}
|
||||
|
||||
void __nd_iostat_start(struct bio *bio, unsigned long *start)
|
||||
{
|
||||
struct gendisk *disk = bio->bi_bdev->bd_disk;
|
||||
const int rw = bio_data_dir(bio);
|
||||
int cpu = part_stat_lock();
|
||||
|
||||
*start = jiffies;
|
||||
part_round_stats(cpu, &disk->part0);
|
||||
part_stat_inc(cpu, &disk->part0, ios[rw]);
|
||||
part_stat_add(cpu, &disk->part0, sectors[rw], bio_sectors(bio));
|
||||
part_inc_in_flight(&disk->part0, rw);
|
||||
part_stat_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(__nd_iostat_start);
|
||||
|
||||
void nd_iostat_end(struct bio *bio, unsigned long start)
|
||||
{
|
||||
struct gendisk *disk = bio->bi_bdev->bd_disk;
|
||||
unsigned long duration = jiffies - start;
|
||||
const int rw = bio_data_dir(bio);
|
||||
int cpu = part_stat_lock();
|
||||
|
||||
part_stat_add(cpu, &disk->part0, ticks[rw], duration);
|
||||
part_round_stats(cpu, &disk->part0);
|
||||
part_dec_in_flight(&disk->part0, rw);
|
||||
part_stat_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(nd_iostat_end);
|
||||
|
||||
static ssize_t commands_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ static int nvdimm_probe(struct device *dev)
|
|||
nd_label_copy(ndd, to_next_namespace_index(ndd),
|
||||
to_current_namespace_index(ndd));
|
||||
rc = nd_label_reserve_dpa(ndd);
|
||||
if (ndd->ns_current >= 0)
|
||||
nvdimm_set_aliasing(dev);
|
||||
nvdimm_bus_unlock(dev);
|
||||
|
||||
if (rc)
|
||||
|
|
|
|||
|
|
@ -184,6 +184,13 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
|
|||
return rc;
|
||||
}
|
||||
|
||||
void nvdimm_set_aliasing(struct device *dev)
|
||||
{
|
||||
struct nvdimm *nvdimm = to_nvdimm(dev);
|
||||
|
||||
nvdimm->flags |= NDD_ALIASING;
|
||||
}
|
||||
|
||||
static void nvdimm_release(struct device *dev)
|
||||
{
|
||||
struct nvdimm *nvdimm = to_nvdimm(dev);
|
||||
|
|
|
|||
|
|
@ -84,18 +84,8 @@ static struct platform_driver e820_pmem_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static __init int e820_pmem_init(void)
|
||||
{
|
||||
return platform_driver_register(&e820_pmem_driver);
|
||||
}
|
||||
|
||||
static __exit void e820_pmem_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&e820_pmem_driver);
|
||||
}
|
||||
module_platform_driver(e820_pmem_driver);
|
||||
|
||||
MODULE_ALIAS("platform:e820_pmem*");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Intel Corporation");
|
||||
module_init(e820_pmem_init);
|
||||
module_exit(e820_pmem_exit);
|
||||
|
|
|
|||
|
|
@ -938,7 +938,7 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region,
|
|||
}
|
||||
|
||||
for_each_dpa_resource(ndd, res)
|
||||
if (strncmp(res->name, "pmem", 3) == 0)
|
||||
if (strncmp(res->name, "pmem", 4) == 0)
|
||||
count++;
|
||||
WARN_ON_ONCE(!count);
|
||||
|
||||
|
|
|
|||
|
|
@ -1132,7 +1132,7 @@ static ssize_t size_show(struct device *dev,
|
|||
return sprintf(buf, "%llu\n", (unsigned long long)
|
||||
nvdimm_namespace_capacity(to_ndns(dev)));
|
||||
}
|
||||
static DEVICE_ATTR(size, S_IRUGO, size_show, size_store);
|
||||
static DEVICE_ATTR(size, 0444, size_show, size_store);
|
||||
|
||||
static u8 *namespace_to_uuid(struct device *dev)
|
||||
{
|
||||
|
|
@ -1456,7 +1456,7 @@ static umode_t namespace_visible(struct kobject *kobj,
|
|||
|
||||
if (is_namespace_pmem(dev) || is_namespace_blk(dev)) {
|
||||
if (a == &dev_attr_size.attr)
|
||||
return S_IWUSR | S_IRUGO;
|
||||
return 0644;
|
||||
|
||||
if (is_namespace_pmem(dev) && a == &dev_attr_sector_size.attr)
|
||||
return 0;
|
||||
|
|
@ -1653,7 +1653,7 @@ static int select_pmem_id(struct nd_region *nd_region, u8 *pmem_id)
|
|||
u64 hw_start, hw_end, pmem_start, pmem_end;
|
||||
struct nd_label_ent *label_ent;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&nd_mapping->lock));
|
||||
lockdep_assert_held(&nd_mapping->lock);
|
||||
list_for_each_entry(label_ent, &nd_mapping->labels, list) {
|
||||
nd_label = label_ent->label;
|
||||
if (!nd_label)
|
||||
|
|
@ -1997,7 +1997,7 @@ struct device *create_namespace_blk(struct nd_region *nd_region,
|
|||
struct nd_mapping *nd_mapping = &nd_region->mapping[0];
|
||||
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
|
||||
struct nd_namespace_blk *nsblk;
|
||||
char *name[NSLABEL_NAME_LEN];
|
||||
char name[NSLABEL_NAME_LEN];
|
||||
struct device *dev = NULL;
|
||||
struct resource *res;
|
||||
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ int nvdimm_set_config_data(struct nvdimm_drvdata *ndd, size_t offset,
|
|||
void *buf, size_t len);
|
||||
long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
|
||||
unsigned int len);
|
||||
void nvdimm_set_aliasing(struct device *dev);
|
||||
struct nd_btt *to_nd_btt(struct device *dev);
|
||||
|
||||
struct nd_gen_sb {
|
||||
|
|
@ -377,10 +378,17 @@ static inline bool nd_iostat_start(struct bio *bio, unsigned long *start)
|
|||
if (!blk_queue_io_stat(disk->queue))
|
||||
return false;
|
||||
|
||||
__nd_iostat_start(bio, start);
|
||||
*start = jiffies;
|
||||
generic_start_io_acct(bio_data_dir(bio),
|
||||
bio_sectors(bio), &disk->part0);
|
||||
return true;
|
||||
}
|
||||
void nd_iostat_end(struct bio *bio, unsigned long start);
|
||||
static inline void nd_iostat_end(struct bio *bio, unsigned long start)
|
||||
{
|
||||
struct gendisk *disk = bio->bi_bdev->bd_disk;
|
||||
|
||||
generic_end_io_acct(bio_data_dir(bio), &disk->part0, start);
|
||||
}
|
||||
static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
|
||||
unsigned int len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ static ssize_t align_show(struct device *dev,
|
|||
{
|
||||
struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev);
|
||||
|
||||
return sprintf(buf, "%lx\n", nd_pfn->align);
|
||||
return sprintf(buf, "%ld\n", nd_pfn->align);
|
||||
}
|
||||
|
||||
static ssize_t __align_store(struct nd_pfn *nd_pfn, const char *buf)
|
||||
|
|
|
|||
|
|
@ -53,21 +53,24 @@ static int pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset,
|
|||
struct device *dev = to_dev(pmem);
|
||||
sector_t sector;
|
||||
long cleared;
|
||||
int rc = 0;
|
||||
|
||||
sector = (offset - pmem->data_offset) / 512;
|
||||
cleared = nvdimm_clear_poison(dev, pmem->phys_addr + offset, len);
|
||||
|
||||
cleared = nvdimm_clear_poison(dev, pmem->phys_addr + offset, len);
|
||||
if (cleared < len)
|
||||
rc = -EIO;
|
||||
if (cleared > 0 && cleared / 512) {
|
||||
dev_dbg(dev, "%s: %#llx clear %ld sector%s\n",
|
||||
__func__, (unsigned long long) sector,
|
||||
cleared / 512, cleared / 512 > 1 ? "s" : "");
|
||||
badblocks_clear(&pmem->bb, sector, cleared / 512);
|
||||
} else {
|
||||
return -EIO;
|
||||
cleared /= 512;
|
||||
dev_dbg(dev, "%s: %#llx clear %ld sector%s\n", __func__,
|
||||
(unsigned long long) sector, cleared,
|
||||
cleared > 1 ? "s" : "");
|
||||
badblocks_clear(&pmem->bb, sector, cleared);
|
||||
}
|
||||
|
||||
invalidate_pmem(pmem->virt_addr + offset, len);
|
||||
return 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void write_pmem(void *pmem_addr, struct page *page,
|
||||
|
|
@ -270,7 +273,7 @@ static int pmem_attach_disk(struct device *dev,
|
|||
dev_warn(dev, "unable to guarantee persistence of writes\n");
|
||||
|
||||
if (!devm_request_mem_region(dev, res->start, resource_size(res),
|
||||
dev_name(dev))) {
|
||||
dev_name(&ndns->dev))) {
|
||||
dev_warn(dev, "could not reserve region %pR\n", res);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -509,7 +509,7 @@ void nd_mapping_free_labels(struct nd_mapping *nd_mapping)
|
|||
{
|
||||
struct nd_label_ent *label_ent, *e;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&nd_mapping->lock));
|
||||
lockdep_assert_held(&nd_mapping->lock);
|
||||
list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
|
||||
list_del(&label_ent->list);
|
||||
kfree(label_ent);
|
||||
|
|
|
|||
Loading…
Reference in a new issue