distress = 100 >> min(zone->prev_priority, priority); mapped_ratio = ((global_page_state(NR_FILE_MAPPED) +

global_page_state(NR_ANON_PAGES)) * 100) / vm_total_pages; mapped_ratio = (sc->nr_mapped * 100) / total_memory; swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;

imbalance = zone_page_state(zone, NR_ACTIVE);

imbalance /= zone_page_state(zone, NR_INACTIVE) + 1;

imbalance /= 100;

imbalance *= mapped_ratio;

imbalance /= 100;

swap_tendency += imbalance; if (swap_tendency >= 100)

reclaim_mapped = 1;

refill_inactive_zone lru_add_drain isolate_lru_pages

Compute Swap Parameters

Figure 18-15: Code flow diagram for refill_inactive_zone (Part 1).

Four values, whose meanings are given below, are calculated12:

□ distress is the key indicator as to how urgently the kernel needs fresh memory. It is calculated using the prev_priority value for right-shifting the fixed value 100. prev_priority specifies the priority with which the zone had to be scanned during the last try_to_free_pages run until the required number of pages was freed. Notice that the lower prev_priority is, the higher the priority. The shift operations produce the following distress values for various priorities:

Priority Distress

















All priority values greater than 7 yield a distress factor of 0. While 0 ensures the kernel that there is no problem at all, 100 indicates massive trouble.

□ mapped_ratio indicates the ratio of mapped memory pages (not only used to cache data but also explicitly requested by processes to store data) to the total available memory. The ratio is calculated by dividing the current number of mapped pages by the total number of pages available at system start. The result is scaled to a percentage value by multiplying by 100.

□ mapped_ratio is used only to calculate a further value that is called swap_tendency and — as its name suggests — indicates the swap tendency of the system. You are already familiar with the first two calculation variables. sc_swappiness is an additional kernel parameter that is usually based on the setting in /proc/sys/vm/swappiness.

□ If there is a large imbalance between the lengths of the active and inactive lists, the kernel allows swapping and page reclaim to happen more easily than usual to balance the situation. However, some effort is made that large imbalances do not have much influence at low swappiness values.

□ The kernel now reduces all the information calculated so far to a truth value that answers the following question: Are mapped pages to be swapped out or not?

If swap_tendency is greater than or equal to 100, mapped pages are also swapped out, and reclaim_mapped is set to 1. Otherwise, the variable retains its default value of 0 so that pages are only reclaimed from the page cache.

As vm_swappiness is added to swap_tendency, the administrator can enable the swapping of mapped pages at any time regardless of the other system parameters by assigning the value of 100 to the variable.

The lru_add_drain procedure, which is invoked after the parameters have been calculated, distributes the data currently held in the LRU cache to the system's LRU lists. In contrast to lru_cache_add, touched upon in Section 18.6.2, copying is performed when the temporary caches contain at least one element, not only when they are completely filled.

12The individual formulas were derived heuristically and are designed to guarantee good performance in many different situations.

Ultimately, the task of shrink_active_list is to move a specific number of pages in the list of active pages in a zone back to the list of active or inactive pages in a zone. Three local lists, on which page instances can be buffered, are created to enable the pages to be scanned:

□ l_active and l_inactive hold pages that are to be put back on the list of active or inactive pages of the zone at the end of the function.

□ l_hold stores pages still to be scanned before it is decided to which list they are returned.

This task is delegated to isolate_lru_pages discussed just above. Recall that the function reads the LRU list from tail to head, but arranges the pages in opposite order on the temporary local list. This is a key point when implementing the LRU algorithm for page replacement. The seldom-used pages on the active list automatically move to the rear. As a result, the kernel finds it very easy to scan the least-used pages because they are located at the beginning of the l_hold list.

The second section of refill_inactive_list begins once the parameters have been calculated. In this section, the individual pages are distributed to the l_active and l_inactive lists of the zone. Instead of using a code flow diagram to show how this is done, let's reproduce and discuss the relevant code:

Continue reading here: Mmvmscanc

Was this article helpful?

0 0