summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2019-04-20 08:06:37 -0400
committerBorislav Petkov <bp@suse.de>2019-06-08 11:33:10 -0400
commitde0e0624d86ff9fc512dedb297f8978698abf21a (patch)
tree28d6d96ec9e4765a65a096cf1e26d0611e929193
parent6d8e294bf5f0e85c34e8b14b064e2965f53f38b0 (diff)
RAS/CEC: Check count_threshold unconditionally
The count_threshold should be checked unconditionally, after insertion too, so that a count_threshold value of 1 can cause an immediate offlining. I.e., offline the page on the *first* error encountered. Add comments to make it clear what cec_add_elem() does, while at it. Reported-by: WANG Chao <chao.wang@ucloud.cn> Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Tony Luck <tony.luck@intel.com> Cc: linux-edac@vger.kernel.org Link: https://lkml.kernel.org/r/20190418034115.75954-3-chao.wang@ucloud.cn
-rw-r--r--drivers/ras/cec.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/ras/cec.c b/drivers/ras/cec.c
index f5795adc5a6e..73a975c26f9f 100644
--- a/drivers/ras/cec.c
+++ b/drivers/ras/cec.c
@@ -294,6 +294,7 @@ int cec_add_elem(u64 pfn)
294 294
295 ca->ces_entered++; 295 ca->ces_entered++;
296 296
297 /* Array full, free the LRU slot. */
297 if (ca->n == MAX_ELEMS) 298 if (ca->n == MAX_ELEMS)
298 WARN_ON(!del_lru_elem_unlocked(ca)); 299 WARN_ON(!del_lru_elem_unlocked(ca));
299 300
@@ -306,24 +307,17 @@ int cec_add_elem(u64 pfn)
306 (void *)&ca->array[to], 307 (void *)&ca->array[to],
307 (ca->n - to) * sizeof(u64)); 308 (ca->n - to) * sizeof(u64));
308 309
309 ca->array[to] = (pfn << PAGE_SHIFT) | 310 ca->array[to] = pfn << PAGE_SHIFT;
310 (DECAY_MASK << COUNT_BITS) | 1;
311
312 ca->n++; 311 ca->n++;
313
314 ret = 0;
315
316 goto decay;
317 } 312 }
318 313
319 count = COUNT(ca->array[to]); 314 /* Add/refresh element generation and increment count */
320 315 ca->array[to] |= DECAY_MASK << COUNT_BITS;
321 if (count < count_threshold) { 316 ca->array[to]++;
322 ca->array[to] |= (DECAY_MASK << COUNT_BITS);
323 ca->array[to]++;
324 317
325 ret = 0; 318 /* Check action threshold and soft-offline, if reached. */
326 } else { 319 count = COUNT(ca->array[to]);
320 if (count >= count_threshold) {
327 u64 pfn = ca->array[to] >> PAGE_SHIFT; 321 u64 pfn = ca->array[to] >> PAGE_SHIFT;
328 322
329 if (!pfn_valid(pfn)) { 323 if (!pfn_valid(pfn)) {
@@ -338,15 +332,14 @@ int cec_add_elem(u64 pfn)
338 del_elem(ca, to); 332 del_elem(ca, to);
339 333
340 /* 334 /*
341 * Return a >0 value to denote that we've reached the offlining 335 * Return a >0 value to callers, to denote that we've reached
342 * threshold. 336 * the offlining threshold.
343 */ 337 */
344 ret = 1; 338 ret = 1;
345 339
346 goto unlock; 340 goto unlock;
347 } 341 }
348 342
349decay:
350 ca->decay_count++; 343 ca->decay_count++;
351 344
352 if (ca->decay_count >= CLEAN_ELEMS) 345 if (ca->decay_count >= CLEAN_ELEMS)