Commit f4b7e272 authored by Andrey Ryabinin's avatar Andrey Ryabinin Committed by Linus Torvalds
Browse files

mm: remove zone_lru_lock() function, access ->lru_lock directly

We have common pattern to access lru_lock from a page pointer:
	zone_lru_lock(page_zone(page))

Which is silly, because it unfolds to this:
	&NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)]->zone_pgdat->lru_lock
while we can simply do
	&NODE_DATA(page_to_nid(page))->lru_lock

Remove zone_lru_lock() function, since it's only complicate things.  Use
'page_pgdat(page)->lru_lock' pattern instead.

[aryabinin@virtuozzo.com: a slightly better version of __split_huge_page()]
  Link: http://lkml.kernel.org/r/20190301121651.7741-1-aryabinin@virtuozzo.com
Link: http://lkml.kernel.org/r/20190228083329.31892-2-aryabinin@virtuozzo.com


Signed-off-by: default avatarAndrey Ryabinin <aryabinin@virtuozzo.com>
Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
Acked-by: default avatarMel Gorman <mgorman@techsingularity.net>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: John Hubbard <jhubbard@nvidia.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a7ca12f9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -107,9 +107,9 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y.

8. LRU
        Each memcg has its own private LRU. Now, its handling is under global
	VM's control (means that it's handled under global zone_lru_lock).
	VM's control (means that it's handled under global pgdat->lru_lock).
	Almost all routines around memcg's LRU is called by global LRU's
	list management functions under zone_lru_lock().
	list management functions under pgdat->lru_lock.

	A special function is mem_cgroup_isolate_pages(). This scans
	memcg's private LRU and call __isolate_lru_page() to extract a page
+2 −2
Original line number Diff line number Diff line
@@ -267,11 +267,11 @@ When oom event notifier is registered, event will be delivered.
   Other lock order is following:
   PG_locked.
   mm->page_table_lock
       zone_lru_lock
       pgdat->lru_lock
	  lock_page_cgroup.
  In many cases, just lock_page_cgroup() is called.
  per-zone-per-cgroup LRU (cgroup's private LRU) is just guarded by
  zone_lru_lock, it has no lock of its own.
  pgdat->lru_lock, it has no lock of its own.

2.7 Kernel Memory Extension (CONFIG_MEMCG_KMEM)

+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ struct page {
		struct {	/* Page cache and anonymous pages */
			/**
			 * @lru: Pageout list, eg. active_list protected by
			 * zone_lru_lock.  Sometimes used as a generic list
			 * pgdat->lru_lock.  Sometimes used as a generic list
			 * by the page owner.
			 */
			struct list_head lru;
+0 −4
Original line number Diff line number Diff line
@@ -730,10 +730,6 @@ typedef struct pglist_data {

#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) pgdat_end_pfn(NODE_DATA(nid))
static inline spinlock_t *zone_lru_lock(struct zone *zone)
{
	return &zone->zone_pgdat->lru_lock;
}

static inline struct lruvec *node_lruvec(struct pglist_data *pgdat)
{
+8 −7
Original line number Diff line number Diff line
@@ -775,6 +775,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
			unsigned long end_pfn, isolate_mode_t isolate_mode)
{
	struct zone *zone = cc->zone;
	pg_data_t *pgdat = zone->zone_pgdat;
	unsigned long nr_scanned = 0, nr_isolated = 0;
	struct lruvec *lruvec;
	unsigned long flags = 0;
@@ -839,8 +840,8 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
		 * if contended.
		 */
		if (!(low_pfn % SWAP_CLUSTER_MAX)
		    && compact_unlock_should_abort(zone_lru_lock(zone), flags,
								&locked, cc))
		    && compact_unlock_should_abort(&pgdat->lru_lock,
					    flags, &locked, cc))
			break;

		if (!pfn_valid_within(low_pfn))
@@ -910,7 +911,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
			if (unlikely(__PageMovable(page)) &&
					!PageIsolated(page)) {
				if (locked) {
					spin_unlock_irqrestore(zone_lru_lock(zone),
					spin_unlock_irqrestore(&pgdat->lru_lock,
									flags);
					locked = false;
				}
@@ -940,7 +941,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,

		/* If we already hold the lock, we can skip some rechecking */
		if (!locked) {
			locked = compact_lock_irqsave(zone_lru_lock(zone),
			locked = compact_lock_irqsave(&pgdat->lru_lock,
								&flags, cc);

			/* Try get exclusive access under lock */
@@ -965,7 +966,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
			}
		}

		lruvec = mem_cgroup_page_lruvec(page, zone->zone_pgdat);
		lruvec = mem_cgroup_page_lruvec(page, pgdat);

		/* Try isolate the page */
		if (__isolate_lru_page(page, isolate_mode) != 0)
@@ -1007,7 +1008,7 @@ isolate_fail:
		 */
		if (nr_isolated) {
			if (locked) {
				spin_unlock_irqrestore(zone_lru_lock(zone), flags);
				spin_unlock_irqrestore(&pgdat->lru_lock, flags);
				locked = false;
			}
			putback_movable_pages(&cc->migratepages);
@@ -1034,7 +1035,7 @@ isolate_fail:

isolate_abort:
	if (locked)
		spin_unlock_irqrestore(zone_lru_lock(zone), flags);
		spin_unlock_irqrestore(&pgdat->lru_lock, flags);

	/*
	 * Updated the cached scanner pfn once the pageblock has been scanned
Loading