Merge tag 'libnvdimm-fixes-4.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
Pull libnvdimm fixes from Dave Jiang: - ensure that a variable passed in by reference to acpi_nfit_ctl is always set to a value. An incremental patch is provided due to notice from testing in -next. The rest of the commits did not exhibit issues. - fix a return path in nsio_rw_bytes() that was not returning "bytes remain" as expected for the function. - address an issue where applications polling on scrub-completion for the NVDIMM may falsely wakeup and read the wrong state value and cause hang. - change the test unit persistent capability attribute to fix up a broken assumption in the unit test infrastructure wrt the 'write_cache' attribute - ratelimit dev_info() in the dax device check_vma() function since this is easily triggered from userspace * tag 'libnvdimm-fixes-4.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm: nfit: fix unchecked dereference in acpi_nfit_ctl acpi, nfit: Fix scrub idle detection tools/testing/nvdimm: advertise a write cache for nfit_test acpi/nfit: fix cmd_rc for acpi_nfit_ctl to always return a value dev-dax: check_vma: ratelimit dev_info-s libnvdimm, pmem: Fix memcpy_mcsafe() return code handling in nsio_rw_bytes()
Cette révision appartient à :
@@ -408,6 +408,8 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
|
||||
const guid_t *guid;
|
||||
int rc, i;
|
||||
|
||||
if (cmd_rc)
|
||||
*cmd_rc = -EINVAL;
|
||||
func = cmd;
|
||||
if (cmd == ND_CMD_CALL) {
|
||||
call_pkg = buf;
|
||||
@@ -518,6 +520,8 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
|
||||
* If we return an error (like elsewhere) then caller wouldn't
|
||||
* be able to rely upon data returned to make calculation.
|
||||
*/
|
||||
if (cmd_rc)
|
||||
*cmd_rc = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1273,7 +1277,7 @@ static ssize_t scrub_show(struct device *dev,
|
||||
|
||||
mutex_lock(&acpi_desc->init_mutex);
|
||||
rc = sprintf(buf, "%d%s", acpi_desc->scrub_count,
|
||||
work_busy(&acpi_desc->dwork.work)
|
||||
acpi_desc->scrub_busy
|
||||
&& !acpi_desc->cancel ? "+\n" : "\n");
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
}
|
||||
@@ -2939,6 +2943,32 @@ static unsigned int __acpi_nfit_scrub(struct acpi_nfit_desc *acpi_desc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __sched_ars(struct acpi_nfit_desc *acpi_desc, unsigned int tmo)
|
||||
{
|
||||
lockdep_assert_held(&acpi_desc->init_mutex);
|
||||
|
||||
acpi_desc->scrub_busy = 1;
|
||||
/* note this should only be set from within the workqueue */
|
||||
if (tmo)
|
||||
acpi_desc->scrub_tmo = tmo;
|
||||
queue_delayed_work(nfit_wq, &acpi_desc->dwork, tmo * HZ);
|
||||
}
|
||||
|
||||
static void sched_ars(struct acpi_nfit_desc *acpi_desc)
|
||||
{
|
||||
__sched_ars(acpi_desc, 0);
|
||||
}
|
||||
|
||||
static void notify_ars_done(struct acpi_nfit_desc *acpi_desc)
|
||||
{
|
||||
lockdep_assert_held(&acpi_desc->init_mutex);
|
||||
|
||||
acpi_desc->scrub_busy = 0;
|
||||
acpi_desc->scrub_count++;
|
||||
if (acpi_desc->scrub_count_state)
|
||||
sysfs_notify_dirent(acpi_desc->scrub_count_state);
|
||||
}
|
||||
|
||||
static void acpi_nfit_scrub(struct work_struct *work)
|
||||
{
|
||||
struct acpi_nfit_desc *acpi_desc;
|
||||
@@ -2949,14 +2979,10 @@ static void acpi_nfit_scrub(struct work_struct *work)
|
||||
mutex_lock(&acpi_desc->init_mutex);
|
||||
query_rc = acpi_nfit_query_poison(acpi_desc);
|
||||
tmo = __acpi_nfit_scrub(acpi_desc, query_rc);
|
||||
if (tmo) {
|
||||
queue_delayed_work(nfit_wq, &acpi_desc->dwork, tmo * HZ);
|
||||
acpi_desc->scrub_tmo = tmo;
|
||||
} else {
|
||||
acpi_desc->scrub_count++;
|
||||
if (acpi_desc->scrub_count_state)
|
||||
sysfs_notify_dirent(acpi_desc->scrub_count_state);
|
||||
}
|
||||
if (tmo)
|
||||
__sched_ars(acpi_desc, tmo);
|
||||
else
|
||||
notify_ars_done(acpi_desc);
|
||||
memset(acpi_desc->ars_status, 0, acpi_desc->max_ars);
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
}
|
||||
@@ -3037,7 +3063,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
||||
break;
|
||||
}
|
||||
|
||||
queue_delayed_work(nfit_wq, &acpi_desc->dwork, 0);
|
||||
sched_ars(acpi_desc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3239,7 +3265,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, unsigned long flags)
|
||||
}
|
||||
}
|
||||
if (scheduled) {
|
||||
queue_delayed_work(nfit_wq, &acpi_desc->dwork, 0);
|
||||
sched_ars(acpi_desc);
|
||||
dev_dbg(dev, "ars_scan triggered\n");
|
||||
}
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
|
@@ -203,6 +203,7 @@ struct acpi_nfit_desc {
|
||||
unsigned int max_ars;
|
||||
unsigned int scrub_count;
|
||||
unsigned int scrub_mode;
|
||||
unsigned int scrub_busy:1;
|
||||
unsigned int cancel:1;
|
||||
unsigned long dimm_cmd_force_en;
|
||||
unsigned long bus_cmd_force_en;
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur