DF-4906 / fix.diff
--- a/sys/dev/powermng/powernow/powernow.c +++ b/sys/dev/powermng/powernow/powernow.c @@ -81,10 +81,19 @@ #define FID_TO_VCO_FID(fid) \ (((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) +/* DF-4906: bounded wait -- a stuck change-pending bit must abort + * the transition instead of spinning forever in kernel context. */ +#define READ_PENDING_WAIT_MAX 1000000 #define READ_PENDING_WAIT(status) \ do { \ - (status) = rdmsr(MSR_AMDK7_FIDVID_STATUS); \ - } while (PN8_STA_PENDING(status)) + int pw_; \ + for (pw_ = 0; pw_ < READ_PENDING_WAIT_MAX; pw_++) { \ + (status) = rdmsr(MSR_AMDK7_FIDVID_STATUS); \ + if (!PN8_STA_PENDING(status)) \ + break; \ + DELAY(1); \ + } \ + } while (0) #define abs(x) ( (x) < 0 ? -(x) : (x) ) #define POWERNOW_MAX_STATES 16 |