Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d46d0256 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'akpm' (patches from Andrew)

Merge various fixes from Andrew Morton:
 "10 fixes"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  mm, page_alloc: recalculate the preferred zoneref if the context can ignore memory policies
  mm, page_alloc: reset zonelist iterator after resetting fair zone allocation policy
  mm, oom_reaper: do not use siglock in try_oom_reaper()
  mm, page_alloc: prevent infinite loop in buffered_rmqueue()
  checkpatch: reduce git commit description style false positives
  mm/z3fold.c: avoid modifying HEADLESS page and minor cleanup
  memcg: add RCU locking around css_for_each_descendant_pre() in memcg_offline_kmem()
  mm: check the return value of lookup_page_ext for all call sites
  kdump: fix dmesg gdbmacro to work with record based printk
  mm: fix overflow in vm_map_ram()
parents 8c52b6dc e46e7b77
Loading
Loading
Loading
Loading
+82 −11
Original line number Diff line number Diff line
@@ -170,21 +170,92 @@ document trapinfo
	address the kernel panicked.
end

define dump_log_idx
	set $idx = $arg0
	if ($argc > 1)
		set $prev_flags = $arg1
	else
		set $prev_flags = 0
	end
	set $msg = ((struct printk_log *) (log_buf + $idx))
	set $prefix = 1
	set $newline = 1
	set $log = log_buf + $idx + sizeof(*$msg)

define dmesg
	set $i = 0
	set $end_idx = (log_end - 1) & (log_buf_len - 1)
	# prev & LOG_CONT && !(msg->flags & LOG_PREIX)
	if (($prev_flags & 8) && !($msg->flags & 4))
		set $prefix = 0
	end

	while ($i < logged_chars)
		set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1)
	# msg->flags & LOG_CONT
	if ($msg->flags & 8)
		# (prev & LOG_CONT && !(prev & LOG_NEWLINE))
		if (($prev_flags & 8) && !($prev_flags & 2))
			set $prefix = 0
		end
		# (!(msg->flags & LOG_NEWLINE))
		if (!($msg->flags & 2))
			set $newline = 0
		end
	end

		if ($idx + 100 <= $end_idx) || \
		   ($end_idx <= $idx && $idx + 100 < log_buf_len)
			printf "%.100s", &log_buf[$idx]
			set $i = $i + 100
	if ($prefix)
		printf "[%5lu.%06lu] ", $msg->ts_nsec / 1000000000, $msg->ts_nsec % 1000000000
	end
	if ($msg->text_len != 0)
		eval "printf \"%%%d.%ds\", $log", $msg->text_len, $msg->text_len
	end
	if ($newline)
		printf "\n"
	end
	if ($msg->dict_len > 0)
		set $dict = $log + $msg->text_len
		set $idx = 0
		set $line = 1
		while ($idx < $msg->dict_len)
			if ($line)
				printf " "
				set $line = 0
			end
			set $c = $dict[$idx]
			if ($c == '\0')
				printf "\n"
				set $line = 1
			else
				if ($c < ' ' || $c >= 127 || $c == '\\')
					printf "\\x%02x", $c
				else
			printf "%c", log_buf[$idx]
			set $i = $i + 1
					printf "%c", $c
				end
			end
			set $idx = $idx + 1
		end
		printf "\n"
	end
end
document dump_log_idx
	Dump a single log given its index in the log buffer.  The first
	parameter is the index into log_buf, the second is optional and
	specified the previous log buffer's flags, used for properly
	formatting continued lines.
end

define dmesg
	set $i = log_first_idx
	set $end_idx = log_first_idx
	set $prev_flags = 0

	while (1)
		set $msg = ((struct printk_log *) (log_buf + $i))
		if ($msg->len == 0)
			set $i = 0
		else
			dump_log_idx $i $prev_flags
			set $i = $i + $msg->len
			set $prev_flags = $msg->flags
		end
		if ($i == $end_idx)
			loop_break
		end
	end
end
+36 −7
Original line number Diff line number Diff line
@@ -46,33 +46,62 @@ extern struct page_ext_operations page_idle_ops;

static inline bool page_is_young(struct page *page)
{
	return test_bit(PAGE_EXT_YOUNG, &lookup_page_ext(page)->flags);
	struct page_ext *page_ext = lookup_page_ext(page);

	if (unlikely(!page_ext))
		return false;

	return test_bit(PAGE_EXT_YOUNG, &page_ext->flags);
}

static inline void set_page_young(struct page *page)
{
	set_bit(PAGE_EXT_YOUNG, &lookup_page_ext(page)->flags);
	struct page_ext *page_ext = lookup_page_ext(page);

	if (unlikely(!page_ext))
		return;

	set_bit(PAGE_EXT_YOUNG, &page_ext->flags);
}

static inline bool test_and_clear_page_young(struct page *page)
{
	return test_and_clear_bit(PAGE_EXT_YOUNG,
				  &lookup_page_ext(page)->flags);
	struct page_ext *page_ext = lookup_page_ext(page);

	if (unlikely(!page_ext))
		return false;

	return test_and_clear_bit(PAGE_EXT_YOUNG, &page_ext->flags);
}

static inline bool page_is_idle(struct page *page)
{
	return test_bit(PAGE_EXT_IDLE, &lookup_page_ext(page)->flags);
	struct page_ext *page_ext = lookup_page_ext(page);

	if (unlikely(!page_ext))
		return false;

	return test_bit(PAGE_EXT_IDLE, &page_ext->flags);
}

static inline void set_page_idle(struct page *page)
{
	set_bit(PAGE_EXT_IDLE, &lookup_page_ext(page)->flags);
	struct page_ext *page_ext = lookup_page_ext(page);

	if (unlikely(!page_ext))
		return;

	set_bit(PAGE_EXT_IDLE, &page_ext->flags);
}

static inline void clear_page_idle(struct page *page)
{
	clear_bit(PAGE_EXT_IDLE, &lookup_page_ext(page)->flags);
	struct page_ext *page_ext = lookup_page_ext(page);

	if (unlikely(!page_ext))
		return;

	clear_bit(PAGE_EXT_IDLE, &page_ext->flags);
}
#endif /* CONFIG_64BIT */

+3 −0
Original line number Diff line number Diff line
@@ -2896,6 +2896,7 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
	 * ordering is imposed by list_lru_node->lock taken by
	 * memcg_drain_all_list_lrus().
	 */
	rcu_read_lock(); /* can be called from css_free w/o cgroup_mutex */
	css_for_each_descendant_pre(css, &memcg->css) {
		child = mem_cgroup_from_css(css);
		BUG_ON(child->kmemcg_id != kmemcg_id);
@@ -2903,6 +2904,8 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
		if (!memcg->use_hierarchy)
			break;
	}
	rcu_read_unlock();

	memcg_drain_all_list_lrus(kmemcg_id, parent->kmemcg_id);

	memcg_free_cache_id(kmemcg_id);
+1 −6
Original line number Diff line number Diff line
@@ -625,8 +625,6 @@ void try_oom_reaper(struct task_struct *tsk)
	if (atomic_read(&mm->mm_users) > 1) {
		rcu_read_lock();
		for_each_process(p) {
			bool exiting;

			if (!process_shares_mm(p, mm))
				continue;
			if (fatal_signal_pending(p))
@@ -636,10 +634,7 @@ void try_oom_reaper(struct task_struct *tsk)
			 * If the task is exiting make sure the whole thread group
			 * is exiting and cannot acces mm anymore.
			 */
			spin_lock_irq(&p->sighand->siglock);
			exiting = signal_group_exit(p->signal);
			spin_unlock_irq(&p->sighand->siglock);
			if (exiting)
			if (signal_group_exit(p->signal))
				continue;

			/* Give up */
+28 −11
Original line number Diff line number Diff line
@@ -656,6 +656,9 @@ static inline void set_page_guard(struct zone *zone, struct page *page,
		return;

	page_ext = lookup_page_ext(page);
	if (unlikely(!page_ext))
		return;

	__set_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);

	INIT_LIST_HEAD(&page->lru);
@@ -673,6 +676,9 @@ static inline void clear_page_guard(struct zone *zone, struct page *page,
		return;

	page_ext = lookup_page_ext(page);
	if (unlikely(!page_ext))
		return;

	__clear_bit(PAGE_EXT_DEBUG_GUARD, &page_ext->flags);

	set_page_private(page, 0);
@@ -2609,11 +2615,12 @@ struct page *buffered_rmqueue(struct zone *preferred_zone,
				page = list_last_entry(list, struct page, lru);
			else
				page = list_first_entry(list, struct page, lru);
		} while (page && check_new_pcp(page));

			__dec_zone_state(zone, NR_ALLOC_BATCH);
			list_del(&page->lru);
			pcp->count--;

		} while (check_new_pcp(page));
	} else {
		/*
		 * We most definitely don't want callers attempting to
@@ -3023,6 +3030,7 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, int alloc_flags,
		apply_fair = false;
		fair_skipped = false;
		reset_alloc_batches(ac->preferred_zoneref->zone);
		z = ac->preferred_zoneref;
		goto zonelist_scan;
	}

@@ -3596,6 +3604,17 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
	 */
	alloc_flags = gfp_to_alloc_flags(gfp_mask);

	/*
	 * Reset the zonelist iterators if memory policies can be ignored.
	 * These allocations are high priority and system rather than user
	 * orientated.
	 */
	if ((alloc_flags & ALLOC_NO_WATERMARKS) || !(alloc_flags & ALLOC_CPUSET)) {
		ac->zonelist = node_zonelist(numa_node_id(), gfp_mask);
		ac->preferred_zoneref = first_zones_zonelist(ac->zonelist,
					ac->high_zoneidx, ac->nodemask);
	}

	/* This is the last chance, in general, before the goto nopage. */
	page = get_page_from_freelist(gfp_mask, order,
				alloc_flags & ~ALLOC_NO_WATERMARKS, ac);
@@ -3604,12 +3623,6 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,

	/* Allocate without watermarks if the context allows */
	if (alloc_flags & ALLOC_NO_WATERMARKS) {
		/*
		 * Ignore mempolicies if ALLOC_NO_WATERMARKS on the grounds
		 * the allocation is high priority and these type of
		 * allocations are system rather than user orientated
		 */
		ac->zonelist = node_zonelist(numa_node_id(), gfp_mask);
		page = get_page_from_freelist(gfp_mask, order,
						ALLOC_NO_WATERMARKS, ac);
		if (page)
@@ -3808,7 +3821,11 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
	/* Dirty zone balancing only done in the fast path */
	ac.spread_dirty_pages = (gfp_mask & __GFP_WRITE);

	/* The preferred zone is used for statistics later */
	/*
	 * The preferred zone is used for statistics but crucially it is
	 * also used as the starting point for the zonelist iterator. It
	 * may get reset for allocations that ignore memory policies.
	 */
	ac.preferred_zoneref = first_zones_zonelist(ac.zonelist,
					ac.high_zoneidx, ac.nodemask);
	if (!ac.preferred_zoneref) {
Loading