Skip to content

Commit cdd77d3

Browse files
committed
nfit, libnvdimm: deprecate the generic SMART ioctl
The kernel's ND_IOCTL_SMART_THRESHOLD command is based on a payload definition that has become broken / out-of-sync with recent versions of the NVDIMM_FAMILY_INTEL definition. Deprecate the use of the ND_IOCTL_SMART_THRESHOLD command in favor of the ND_CMD_CALL approach taken by NVDIMM_FAMILY_{HPE,MSFT}, where we can manage the per-vendor variance in userspace. In a couple years, when the new scheme is widely deployed in userspace packages, the ND_IOCTL_SMART_THRESHOLD support can be removed. For now we prevent new binaries from compiling against the kernel header definitions, but kernel still compatible with old binaries. The libndctl.h [1] header is now the authoritative interface definition for NVDIMM SMART. [1]: https://github.com/pmem/ndctl Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent ae64f9b commit cdd77d3

File tree

4 files changed

+84
-71
lines changed

4 files changed

+84
-71
lines changed

drivers/nvdimm/bus.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,9 +1142,6 @@ int __init nvdimm_bus_init(void)
11421142
{
11431143
int rc;
11441144

1145-
BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
1146-
BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
1147-
11481145
rc = bus_register(&nvdimm_bus_type);
11491146
if (rc)
11501147
return rc;

include/uapi/linux/ndctl.h

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,54 +15,6 @@
1515

1616
#include <linux/types.h>
1717

18-
struct nd_cmd_smart {
19-
__u32 status;
20-
__u8 data[128];
21-
} __packed;
22-
23-
#define ND_SMART_HEALTH_VALID (1 << 0)
24-
#define ND_SMART_SPARES_VALID (1 << 1)
25-
#define ND_SMART_USED_VALID (1 << 2)
26-
#define ND_SMART_TEMP_VALID (1 << 3)
27-
#define ND_SMART_CTEMP_VALID (1 << 4)
28-
#define ND_SMART_ALARM_VALID (1 << 9)
29-
#define ND_SMART_SHUTDOWN_VALID (1 << 10)
30-
#define ND_SMART_VENDOR_VALID (1 << 11)
31-
#define ND_SMART_SPARE_TRIP (1 << 0)
32-
#define ND_SMART_TEMP_TRIP (1 << 1)
33-
#define ND_SMART_CTEMP_TRIP (1 << 2)
34-
#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
35-
#define ND_SMART_CRITICAL_HEALTH (1 << 1)
36-
#define ND_SMART_FATAL_HEALTH (1 << 2)
37-
38-
struct nd_smart_payload {
39-
__u32 flags;
40-
__u8 reserved0[4];
41-
__u8 health;
42-
__u8 spares;
43-
__u8 life_used;
44-
__u8 alarm_flags;
45-
__u16 temperature;
46-
__u16 ctrl_temperature;
47-
__u8 reserved1[15];
48-
__u8 shutdown_state;
49-
__u32 vendor_size;
50-
__u8 vendor_data[92];
51-
} __packed;
52-
53-
struct nd_cmd_smart_threshold {
54-
__u32 status;
55-
__u8 data[8];
56-
} __packed;
57-
58-
struct nd_smart_threshold_payload {
59-
__u8 alarm_control;
60-
__u8 reserved0;
61-
__u16 temperature;
62-
__u8 spares;
63-
__u8 reserved[3];
64-
} __packed;
65-
6618
struct nd_cmd_dimm_flags {
6719
__u32 status;
6820
__u32 flags;
@@ -211,12 +163,6 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
211163

212164
#define ND_IOCTL 'N'
213165

214-
#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART,\
215-
struct nd_cmd_smart)
216-
217-
#define ND_IOCTL_SMART_THRESHOLD _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
218-
struct nd_cmd_smart_threshold)
219-
220166
#define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
221167
struct nd_cmd_dimm_flags)
222168

tools/testing/nvdimm/test/nfit.c

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -440,39 +440,50 @@ static int nfit_test_cmd_translate_spa(struct nvdimm_bus *bus,
440440
return 0;
441441
}
442442

443-
static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
443+
static int nfit_test_cmd_smart(struct nd_intel_smart *smart, unsigned int buf_len)
444444
{
445-
static const struct nd_smart_payload smart_data = {
446-
.flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
447-
| ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
448-
| ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
449-
.health = ND_SMART_NON_CRITICAL_HEALTH,
450-
.temperature = 23 * 16,
445+
static const struct nd_intel_smart smart_data = {
446+
.flags = ND_INTEL_SMART_HEALTH_VALID
447+
| ND_INTEL_SMART_SPARES_VALID
448+
| ND_INTEL_SMART_ALARM_VALID
449+
| ND_INTEL_SMART_USED_VALID
450+
| ND_INTEL_SMART_SHUTDOWN_VALID
451+
| ND_INTEL_SMART_MTEMP_VALID,
452+
.health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
453+
.media_temperature = 23 * 16,
454+
.ctrl_temperature = 30 * 16,
455+
.pmic_temperature = 40 * 16,
451456
.spares = 75,
452-
.alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
457+
.alarm_flags = ND_INTEL_SMART_SPARE_TRIP
458+
| ND_INTEL_SMART_TEMP_TRIP,
459+
.ait_status = 1,
453460
.life_used = 5,
454461
.shutdown_state = 0,
455462
.vendor_size = 0,
463+
.shutdown_count = 100,
456464
};
457465

458466
if (buf_len < sizeof(*smart))
459467
return -EINVAL;
460-
memcpy(smart->data, &smart_data, sizeof(smart_data));
468+
memcpy(smart, &smart_data, sizeof(smart_data));
461469
return 0;
462470
}
463471

464-
static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
472+
static int nfit_test_cmd_smart_threshold(
473+
struct nd_intel_smart_threshold *smart_t,
465474
unsigned int buf_len)
466475
{
467-
static const struct nd_smart_threshold_payload smart_t_data = {
468-
.alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
469-
.temperature = 40 * 16,
476+
static const struct nd_intel_smart_threshold smart_t_data = {
477+
.alarm_control = ND_INTEL_SMART_SPARE_TRIP
478+
| ND_INTEL_SMART_TEMP_TRIP,
479+
.media_temperature = 40 * 16,
480+
.ctrl_temperature = 30 * 16,
470481
.spares = 5,
471482
};
472483

473484
if (buf_len < sizeof(*smart_t))
474485
return -EINVAL;
475-
memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
486+
memcpy(smart_t, &smart_t_data, sizeof(smart_t_data));
476487
return 0;
477488
}
478489

tools/testing/nvdimm/test/nfit_test.h

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,65 @@ struct nd_cmd_ars_err_inj_stat {
8484
} __packed record[0];
8585
} __packed;
8686

87+
#define ND_INTEL_SMART 1
88+
#define ND_INTEL_SMART_THRESHOLD 2
89+
90+
#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
91+
#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
92+
#define ND_INTEL_SMART_USED_VALID (1 << 2)
93+
#define ND_INTEL_SMART_MTEMP_VALID (1 << 3)
94+
#define ND_INTEL_SMART_CTEMP_VALID (1 << 4)
95+
#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID (1 << 5)
96+
#define ND_INTEL_SMART_AIT_STATUS_VALID (1 << 6)
97+
#define ND_INTEL_SMART_PTEMP_VALID (1 << 7)
98+
#define ND_INTEL_SMART_ALARM_VALID (1 << 9)
99+
#define ND_INTEL_SMART_SHUTDOWN_VALID (1 << 10)
100+
#define ND_INTEL_SMART_VENDOR_VALID (1 << 11)
101+
#define ND_INTEL_SMART_SPARE_TRIP (1 << 0)
102+
#define ND_INTEL_SMART_TEMP_TRIP (1 << 1)
103+
#define ND_INTEL_SMART_CTEMP_TRIP (1 << 2)
104+
#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0)
105+
#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1)
106+
#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2)
107+
108+
struct nd_intel_smart {
109+
__u32 status;
110+
union {
111+
struct {
112+
__u32 flags;
113+
__u8 reserved0[4];
114+
__u8 health;
115+
__u8 spares;
116+
__u8 life_used;
117+
__u8 alarm_flags;
118+
__u16 media_temperature;
119+
__u16 ctrl_temperature;
120+
__u32 shutdown_count;
121+
__u8 ait_status;
122+
__u16 pmic_temperature;
123+
__u8 reserved1[8];
124+
__u8 shutdown_state;
125+
__u32 vendor_size;
126+
__u8 vendor_data[92];
127+
} __packed;
128+
__u8 data[128];
129+
};
130+
} __packed;
131+
132+
struct nd_intel_smart_threshold {
133+
__u32 status;
134+
union {
135+
struct {
136+
__u16 alarm_control;
137+
__u8 spares;
138+
__u16 media_temperature;
139+
__u16 ctrl_temperature;
140+
__u8 reserved[1];
141+
} __packed;
142+
__u8 data[8];
143+
};
144+
} __packed;
145+
87146
union acpi_object;
88147
typedef void *acpi_handle;
89148

0 commit comments

Comments
 (0)