Skip to content

Commit fac475a

Browse files
jeshuasmithrafaeljw
authored andcommitted
ACPI: APEI: Use ERST timeout for slow devices
Slow devices such as flash may not meet the default 1ms timeout value, so use the ERST max execution time value that they provide as the timeout if it is larger. Signed-off-by: Jeshua Smith <[email protected]> Reviewed-by: Tony Luck <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent e2abc47 commit fac475a

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

drivers/acpi/apei/erst.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ static struct acpi_table_erst *erst_tab;
5959
#define ERST_RANGE_NVRAM 0x0002
6060
#define ERST_RANGE_SLOW 0x0004
6161

62+
/* ERST Exec max timings */
63+
#define ERST_EXEC_TIMING_MAX_MASK 0xFFFFFFFF00000000
64+
#define ERST_EXEC_TIMING_MAX_SHIFT 32
65+
6266
/*
6367
* ERST Error Log Address Range, used as buffer for reading/writing
6468
* error records.
@@ -68,6 +72,7 @@ static struct erst_erange {
6872
u64 size;
6973
void __iomem *vaddr;
7074
u32 attr;
75+
u64 timings;
7176
} erst_erange;
7277

7378
/*
@@ -97,6 +102,19 @@ static inline int erst_errno(int command_status)
97102
}
98103
}
99104

105+
static inline u64 erst_get_timeout(void)
106+
{
107+
u64 timeout = FIRMWARE_TIMEOUT;
108+
109+
if (erst_erange.attr & ERST_RANGE_SLOW) {
110+
timeout = ((erst_erange.timings & ERST_EXEC_TIMING_MAX_MASK) >>
111+
ERST_EXEC_TIMING_MAX_SHIFT) * NSEC_PER_MSEC;
112+
if (timeout < FIRMWARE_TIMEOUT)
113+
timeout = FIRMWARE_TIMEOUT;
114+
}
115+
return timeout;
116+
}
117+
100118
static int erst_timedout(u64 *t, u64 spin_unit)
101119
{
102120
if ((s64)*t < spin_unit) {
@@ -191,9 +209,11 @@ static int erst_exec_stall_while_true(struct apei_exec_context *ctx,
191209
{
192210
int rc;
193211
u64 val;
194-
u64 timeout = FIRMWARE_TIMEOUT;
212+
u64 timeout;
195213
u64 stall_time;
196214

215+
timeout = erst_get_timeout();
216+
197217
if (ctx->var1 > FIRMWARE_MAX_STALL) {
198218
if (!in_nmi())
199219
pr_warn(FW_WARN
@@ -389,6 +409,13 @@ static int erst_get_erange(struct erst_erange *range)
389409
if (rc)
390410
return rc;
391411
range->attr = apei_exec_ctx_get_output(&ctx);
412+
rc = apei_exec_run(&ctx, ACPI_ERST_EXECUTE_TIMINGS);
413+
if (rc == 0)
414+
range->timings = apei_exec_ctx_get_output(&ctx);
415+
else if (rc == -ENOENT)
416+
range->timings = 0;
417+
else
418+
return rc;
392419

393420
return 0;
394421
}
@@ -621,10 +648,12 @@ EXPORT_SYMBOL_GPL(erst_get_record_id_end);
621648
static int __erst_write_to_storage(u64 offset)
622649
{
623650
struct apei_exec_context ctx;
624-
u64 timeout = FIRMWARE_TIMEOUT;
651+
u64 timeout;
625652
u64 val;
626653
int rc;
627654

655+
timeout = erst_get_timeout();
656+
628657
erst_exec_ctx_init(&ctx);
629658
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE);
630659
if (rc)
@@ -660,10 +689,12 @@ static int __erst_write_to_storage(u64 offset)
660689
static int __erst_read_from_storage(u64 record_id, u64 offset)
661690
{
662691
struct apei_exec_context ctx;
663-
u64 timeout = FIRMWARE_TIMEOUT;
692+
u64 timeout;
664693
u64 val;
665694
int rc;
666695

696+
timeout = erst_get_timeout();
697+
667698
erst_exec_ctx_init(&ctx);
668699
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ);
669700
if (rc)
@@ -703,10 +734,12 @@ static int __erst_read_from_storage(u64 record_id, u64 offset)
703734
static int __erst_clear_from_storage(u64 record_id)
704735
{
705736
struct apei_exec_context ctx;
706-
u64 timeout = FIRMWARE_TIMEOUT;
737+
u64 timeout;
707738
u64 val;
708739
int rc;
709740

741+
timeout = erst_get_timeout();
742+
710743
erst_exec_ctx_init(&ctx);
711744
rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR);
712745
if (rc)

0 commit comments

Comments
 (0)