커널에 배열을 추가한 후 "메모리 부족" 발생

커널에 배열을 추가한 후 "메모리 부족" 발생

추적하려고 합니다 get_page_from_freelist().

정수 포인터를 정의하고 kmalloc()in을 사용하여 초기화 mm/init_mm.c하고 이를 제어하기 위한 시스템 호출을 추가했습니다. 하지만 그 후 컴퓨터를 다시 시작했는데 "메모리 부족" 오류가 표시되었습니다.

배열 크기를 4KB(512개 항목)로 줄였지만 여전히 동일한 오류 메시지가 표시됩니다. 내가 아는 한, 4KB 크기는 커널에 비해 매우 작습니다. 이 문제를 어떻게 처리해야 합니까?

kmalloc()크기를 줄이고 정적으로 할당하려고 시도했기 때문에 배열 크기나 사용량이 문제라고 생각하지 않습니다 .

내 커널 버전은 5.19.9이고 실제 메모리는 32GB입니다. 저는 64비트 우분투 22.04를 사용하고 있습니다.

에서 mm/init-mm.c:

int trace_on;
int trace_idx;
int trace_mod;

int raw_trace[TRACE_SIZE][2];

void setup_initial_init_mm(void *start_code, void *end_code,
               void *end_data, void *brk)
{
    int i;

    trace_on = 0;
    trace_idx = 0;
    trace_mod = 0;

    for (i = 0; i < TRACE_SIZE; i++) {
        raw_trace[I][trace_mod] = 0;
    }
    init_mm.start_code = (unsigned long)start_code;
    init_mm.end_code = (unsigned long)end_code;
    init_mm.end_data = (unsigned long)end_data;
    init_mm.brk = (unsigned long)brk;
}

에서 include/linux/mm_types.h:

#define TRACE_SIZE 0x100
extern int trace_on;
extern int trace_idx;
extern int trace_mod;

extern int raw_trace[TRACE_SIZE][2];

에서 mm/page_alloc.c:

#include <linux/mm_types.h>
extern int trace_on;
extern int trace_idx;
extern int trace_mod;

extern int raw_trace[TRACE_SIZE][2];

static struct page *
get_page_from_freelist(gfp_t gfp_mask, unsigned int order, int alloc_flags,
                        const struct alloc_context *ac)
{
    struct zoneref *z;
    struct zone *zone;
    struct pglist_data *last_pgdat_dirty_limit = NULL;
    bool no_fallback;
    int i;

    if (unlikely(!trace_on && trace_idx > 0)) {
            if (unlikely(trace_idx == TRACE_SIZE))
                trace_idx--;
            for (i = 0; i <= trace_idx; i++) {
                raw_trace[i][0] = 0;
                raw_trace[i][1] = 0;

            }
            trace_idx = 0;
            trace_mod = 0;
    }
retry:
...
try_this_zone:
        page = rmqueue(ac->preferred_zoneref->zone, zone, order,
                gfp_mask, alloc_flags, ac->migratetype);
        if (page) {
            prep_new_page(page, order, gfp_mask, alloc_flags);

            /*
             * If this is a high-order atomic allocation then check
             * if the pageblock should be reserved for the future
             */
            if (unlikely(order && (alloc_flags & ALLOC_HARDER)))
                reserve_highatomic_pageblock(page, zone, order);
            if (unlikely(trace_on)) {
                if (unlikely(trace_idx >= TRACE_SIZE)) {
                    if (trace_mod)  trace_mod = 0;
                    else        trace_mod = 1;
                    trace_idx = 0;
                }
                raw_trace[trace_idx++][trace_mod] = page_to_phys(page);
            }
...

관련 정보