cec.c (6d8e294bf5f0e85c34e8b14b064e2965f53f38b0) | cec.c (de0e0624d86ff9fc512dedb297f8978698abf21a) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/mm.h> 3#include <linux/gfp.h> 4#include <linux/kernel.h> 5#include <linux/workqueue.h> 6 7#include <asm/mce.h> 8 --- 280 unchanged lines hidden (view full) --- 289 */ 290 if (!ce_arr.array || ce_arr.disabled) 291 return -ENODEV; 292 293 mutex_lock(&ce_mutex); 294 295 ca->ces_entered++; 296 | 1// SPDX-License-Identifier: GPL-2.0 2#include <linux/mm.h> 3#include <linux/gfp.h> 4#include <linux/kernel.h> 5#include <linux/workqueue.h> 6 7#include <asm/mce.h> 8 --- 280 unchanged lines hidden (view full) --- 289 */ 290 if (!ce_arr.array || ce_arr.disabled) 291 return -ENODEV; 292 293 mutex_lock(&ce_mutex); 294 295 ca->ces_entered++; 296 |
297 /* Array full, free the LRU slot. */ |
|
297 if (ca->n == MAX_ELEMS) 298 WARN_ON(!del_lru_elem_unlocked(ca)); 299 300 ret = find_elem(ca, pfn, &to); 301 if (ret < 0) { 302 /* 303 * Shift range [to-end] to make room for one more element. 304 */ 305 memmove((void *)&ca->array[to + 1], 306 (void *)&ca->array[to], 307 (ca->n - to) * sizeof(u64)); 308 | 298 if (ca->n == MAX_ELEMS) 299 WARN_ON(!del_lru_elem_unlocked(ca)); 300 301 ret = find_elem(ca, pfn, &to); 302 if (ret < 0) { 303 /* 304 * Shift range [to-end] to make room for one more element. 305 */ 306 memmove((void *)&ca->array[to + 1], 307 (void *)&ca->array[to], 308 (ca->n - to) * sizeof(u64)); 309 |
309 ca->array[to] = (pfn << PAGE_SHIFT) | 310 (DECAY_MASK << COUNT_BITS) | 1; 311 | 310 ca->array[to] = pfn << PAGE_SHIFT; |
312 ca->n++; | 311 ca->n++; |
313 314 ret = 0; 315 316 goto decay; | |
317 } 318 | 312 } 313 |
319 count = COUNT(ca->array[to]); | 314 /* Add/refresh element generation and increment count */ 315 ca->array[to] |= DECAY_MASK << COUNT_BITS; 316 ca->array[to]++; |
320 | 317 |
321 if (count < count_threshold) { 322 ca->array[to] |= (DECAY_MASK << COUNT_BITS); 323 ca->array[to]++; 324 325 ret = 0; 326 } else { | 318 /* Check action threshold and soft-offline, if reached. */ 319 count = COUNT(ca->array[to]); 320 if (count >= count_threshold) { |
327 u64 pfn = ca->array[to] >> PAGE_SHIFT; 328 329 if (!pfn_valid(pfn)) { 330 pr_warn("CEC: Invalid pfn: 0x%llx\n", pfn); 331 } else { 332 /* We have reached max count for this page, soft-offline it. */ 333 pr_err("Soft-offlining pfn: 0x%llx\n", pfn); 334 memory_failure_queue(pfn, MF_SOFT_OFFLINE); 335 ca->pfns_poisoned++; 336 } 337 338 del_elem(ca, to); 339 340 /* | 321 u64 pfn = ca->array[to] >> PAGE_SHIFT; 322 323 if (!pfn_valid(pfn)) { 324 pr_warn("CEC: Invalid pfn: 0x%llx\n", pfn); 325 } else { 326 /* We have reached max count for this page, soft-offline it. */ 327 pr_err("Soft-offlining pfn: 0x%llx\n", pfn); 328 memory_failure_queue(pfn, MF_SOFT_OFFLINE); 329 ca->pfns_poisoned++; 330 } 331 332 del_elem(ca, to); 333 334 /* |
341 * Return a >0 value to denote that we've reached the offlining 342 * threshold. | 335 * Return a >0 value to callers, to denote that we've reached 336 * the offlining threshold. |
343 */ 344 ret = 1; 345 346 goto unlock; 347 } 348 | 337 */ 338 ret = 1; 339 340 goto unlock; 341 } 342 |
349decay: | |
350 ca->decay_count++; 351 352 if (ca->decay_count >= CLEAN_ELEMS) 353 do_spring_cleaning(ca); 354 355unlock: 356 mutex_unlock(&ce_mutex); 357 --- 180 unchanged lines hidden --- | 343 ca->decay_count++; 344 345 if (ca->decay_count >= CLEAN_ELEMS) 346 do_spring_cleaning(ca); 347 348unlock: 349 mutex_unlock(&ce_mutex); 350 --- 180 unchanged lines hidden --- |