<kernel v5.0>
디버그 메모리 -5- (Fault Injection)
디버깅용 페이지 할당 실패 Injection
FAIL_PAGE_ALLOC
alloc_pages()에 대한 디버그 기능으로 fault-injection 처리를 위한 코드가 추가된다.
- “fail_page_alloc=<interval>,<probability>,<space>,<times>” 커널 옵션을 사용하여 FAULT-INJECTION에 대한 4가지 속성을 변경할 수 있다.
should_fail_alloc_page()
mm/page_alloc.c
static noinline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) { return __should_fail_alloc_page(gfp_mask, order); } ALLOW_ERROR_INJECTION(should_fail_alloc_page, TRUE);
__should_fail_alloc_page()
mm/page_alloc.c
static bool __should_fail_alloc_page(gfp_t gfp_mask, unsigned int order) { if (order < fail_page_alloc.min_order) return false; if (gfp_mask & __GFP_NOFAIL) return false; if (fail_page_alloc.ignore_gfp_highmem && (gfp_mask & __GFP_HIGHMEM)) return false; if (fail_page_alloc.ignore_gfp_reclaim && (gfp_mask & __GFP_DIRECT_RECLAIM)) return false; return should_fail(&fail_page_alloc.attr, 1 << order); }
CONFIG_FAIL_PAGE_ALLOC 커널 옵션을 사용하는 경우 디버깅 목적으로 사용되며 fail_page_alloc 전역 객체의 조건을 벗어나는 gfp_mask를 가진 경우 false를 반환한다. 또한 __GFP_NOFAIL 옵션을 사용하는 경우에도 false를 반환한다.
should_fail()
lib/fault-inject.c
/* * This code is stolen from failmalloc-1.0 * http://www.nongnu.org/failmalloc/ */
bool should_fail(struct fault_attr *attr, ssize_t size) { if (in_task()) { unsigned int fail_nth = READ_ONCE(current->fail_nth); if (fail_nth) { if (!WRITE_ONCE(current->fail_nth, fail_nth - 1)) goto fail; return false; } } /* No need to check any other properties if the probability is 0 */ if (attr->probability == 0) return false; if (attr->task_filter && !fail_task(attr, current)) return false; if (atomic_read(&attr->times) == 0) return false; if (atomic_read(&attr->space) > size) { atomic_sub(size, &attr->space); return false; } if (attr->interval > 1) { attr->count++; if (attr->count % attr->interval) return false; } if (attr->probability <= prandom_u32() % 100) return false; if (!fail_stacktrace(attr)) return false; fail: fail_dump(attr); if (atomic_read(&attr->times) != -1) atomic_dec_not_zero(&attr->times); return true; } EXPORT_SYMBOL_GPL(should_fail);
참고
- 디버그 메모리 -1- (Page Alloc) | 문c
- 디버그 메모리 -2- (Page Poisoning) | 문c
- 디버그 메모리 -3- (Page Owner 추적) | 문c
- 디버그 메모리 -4- (Idle Page 추적) | 문c
- 디버그 메모리 -5- (Fault Injection) | 문c – 현재 글
- page_ext_init_flatmem() | 문c
- page_ext_init() | 문c