追跡しようとしていますget_page_from_freelist()
。
整数ポインタを定義し、kmalloc()
inを使用して初期化し、mm/init_mm.c
それを制御するためのシステムコールを追加しました。しかし、その後コンピュータを再起動しましたが、「メモリ不足」エラーが表示されました。
配列サイズを4KB(512項目)に縮小しましたが、まだ同じエラーメッセージが表示されます。私が知る限り、4KBのサイズはカーネルに比べて非常に小さいです。この問題にどのように対処する必要がありますか?
kmalloc()
サイズを小さくして静的に割り当てようとしたため、配列のサイズや使用量が問題ではないと思います。
私のカーネルバージョンは5.19.9で、物理メモリは32GBです。私は64ビットUbuntu 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);
}
...