# compaction: 연속 빈 공간을 만들되 실패를 무한 반복하지 않기

v6.18.37 / mm/compaction.c

빈 페이지 수가 충분해도 고차 order의 연속 블록은 없을 수 있습니다. compaction은 이동 가능한 페이지를 옮겨 빈 공간을 모읍니다. 하지만 이동할 수 없는 페이지가 막고 있다면 같은 시도를 계속하는 데 비용만 들 수 있어 재시도를 잠시 미루기도 합니다.

## compaction_deferred

```c

static bool compaction_deferred(struct zone *zone, int order)
{
	unsigned long defer_limit = 1UL << zone->compact_defer_shift;

	if (order < zone->compact_order_failed)
		return false;

	/* Avoid possible overflow */
	if (++zone->compact_considered >= defer_limit) {
		zone->compact_considered = defer_limit;
		return false;
	}

	trace_mm_compaction_deferred(zone, order);

	return true;
}

```

### 141행

```c

static bool compaction_deferred(struct zone *zone, int order)

```

zone에서 해당 order 요청의 compaction을 이번에는 미룰지 판단합니다. 반환 true의 의미를 함수 이름과 함께 읽으셔야 합니다.

### 143행

```c

	unsigned long defer_limit = 1UL << zone->compact_defer_shift;

```

지연 shift에서 판단 횟수 한도를 계산합니다. shift=3이면 8회이며 8초를 뜻하지 않습니다.

### 145행

```c

	if (order < zone->compact_order_failed)

```

이번 요청이 이전에 실패했다고 기록된 최소 order보다 작은지 봅니다.

### 146행

```c

		return false;

```

작은 요청은 실패 기록의 지연 대상에서 빼고 지금 시도할 수 있도록 false를 반환합니다.

### 149행

```c

	if (++zone->compact_considered >= defer_limit) {

```

고차 요청에 대해 검토 횟수를 하나 늘리고 한도에 도달했는지 확인합니다.

### 150행

```c

		zone->compact_considered = defer_limit;

```

한도에 도달한 카운터를 그 값에 고정하여 계속 증가할 때 발생할 수 있는 overflow를 피합니다.

### 151행

```c

		return false;

```

기다린 횟수가 충분하므로 이번에는 compaction을 미루지 않습니다.

### 154행

```c

	trace_mm_compaction_deferred(zone, order);

```

이번 시도를 지연한 사실을 trace에 남겨 지연 정책의 영향을 관찰할 수 있게 합니다.

### 156행

```c

	return true;

```

이번에는 compaction을 생략하도록 true를 반환합니다. 실제 이동 성공 여부를 반환하는 함수가 아닙니다.

