Commit 9b62e02e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'mm-hotfixes-stable-2024-05-25-09-13' of...

Merge tag 'mm-hotfixes-stable-2024-05-25-09-13' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull misc fixes from Andrew Morton:
 "16 hotfixes, 11 of which are cc:stable.

  A few nilfs2 fixes, the remainder are for MM: a couple of selftests
  fixes, various singletons fixing various issues in various parts"

* tag 'mm-hotfixes-stable-2024-05-25-09-13' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm:
  mm/ksm: fix possible UAF of stable_node
  mm/memory-failure: fix handling of dissolved but not taken off from buddy pages
  mm: /proc/pid/smaps_rollup: avoid skipping vma after getting mmap_lock again
  nilfs2: fix potential hang in nilfs_detach_log_writer()
  nilfs2: fix unexpected freezing of nilfs_segctor_sync()
  nilfs2: fix use-after-free of timer for log writer thread
  selftests/mm: fix build warnings on ppc64
  arm64: patching: fix handling of execmem addresses
  selftests/mm: compaction_test: fix bogus test success and reduce probability of OOM-killer invocation
  selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages
  selftests/mm: compaction_test: fix bogus test success on Aarch64
  mailmap: update email address for Satya Priya
  mm/huge_memory: don't unpoison huge_zero_folio
  kasan, fortify: properly rename memintrinsics
  lib: add version into /proc/allocinfo output
  mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL
parents a0db36ed 90e82349
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -572,7 +572,7 @@ Sarangdhar Joshi <spjoshi@codeaurora.org>
Sascha Hauer <s.hauer@pengutronix.de>
Sahitya Tummala <quic_stummala@quicinc.com> <stummala@codeaurora.org>
Sathishkumar Muruganandam <quic_murugana@quicinc.com> <murugana@codeaurora.org>
Satya Priya <quic_c_skakit@quicinc.com> <skakit@codeaurora.org>
Satya Priya <quic_skakitap@quicinc.com> <quic_c_skakit@quicinc.com> <skakit@codeaurora.org>
S.Çağlar Onur <caglar@pardus.org.tr>
Sayali Lokhande <quic_sayalil@quicinc.com> <sayalil@codeaurora.org>
Sean Christopherson <seanjc@google.com> <sean.j.christopherson@intel.com>
+3 −2
Original line number Diff line number Diff line
@@ -961,13 +961,14 @@ Provides information about memory allocations at all locations in the code
base. Each allocation in the code is identified by its source file, line
number, module (if originates from a loadable module) and the function calling
the allocation. The number of bytes allocated and number of calls at each
location are reported.
location are reported. The first line indicates the version of the file, the
second line is the header listing fields in the file.

Example output.

::

    > sort -rn /proc/allocinfo
    > tail -n +3 /proc/allocinfo | sort -rn
   127664128    31168 mm/page_ext.c:270 func:alloc_page_ext
    56373248     4737 mm/slub.c:2259 func:alloc_slab_page
    14880768     3633 mm/readahead.c:247 func:page_cache_ra_unbounded
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ static void __kprobes *patch_map(void *addr, int fixmap)

	if (image)
		page = phys_to_page(__pa_symbol(addr));
	else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
	else if (IS_ENABLED(CONFIG_EXECMEM))
		page = vmalloc_to_page(addr);
	else
		return addr;
+50 −13
Original line number Diff line number Diff line
@@ -2118,8 +2118,10 @@ static void nilfs_segctor_start_timer(struct nilfs_sc_info *sci)
{
	spin_lock(&sci->sc_state_lock);
	if (!(sci->sc_state & NILFS_SEGCTOR_COMMIT)) {
		if (sci->sc_task) {
			sci->sc_timer.expires = jiffies + sci->sc_interval;
			add_timer(&sci->sc_timer);
		}
		sci->sc_state |= NILFS_SEGCTOR_COMMIT;
	}
	spin_unlock(&sci->sc_state_lock);
@@ -2166,19 +2168,36 @@ static int nilfs_segctor_sync(struct nilfs_sc_info *sci)
	struct nilfs_segctor_wait_request wait_req;
	int err = 0;

	spin_lock(&sci->sc_state_lock);
	init_wait(&wait_req.wq);
	wait_req.err = 0;
	atomic_set(&wait_req.done, 0);
	init_waitqueue_entry(&wait_req.wq, current);

	/*
	 * To prevent a race issue where completion notifications from the
	 * log writer thread are missed, increment the request sequence count
	 * "sc_seq_request" and insert a wait queue entry using the current
	 * sequence number into the "sc_wait_request" queue at the same time
	 * within the lock section of "sc_state_lock".
	 */
	spin_lock(&sci->sc_state_lock);
	wait_req.seq = ++sci->sc_seq_request;
	add_wait_queue(&sci->sc_wait_request, &wait_req.wq);
	spin_unlock(&sci->sc_state_lock);

	init_waitqueue_entry(&wait_req.wq, current);
	add_wait_queue(&sci->sc_wait_request, &wait_req.wq);
	set_current_state(TASK_INTERRUPTIBLE);
	wake_up(&sci->sc_wait_daemon);

	for (;;) {
		set_current_state(TASK_INTERRUPTIBLE);

		/*
		 * Synchronize only while the log writer thread is alive.
		 * Leave flushing out after the log writer thread exits to
		 * the cleanup work in nilfs_segctor_destroy().
		 */
		if (!sci->sc_task)
			break;

		if (atomic_read(&wait_req.done)) {
			err = wait_req.err;
			break;
@@ -2194,7 +2213,7 @@ static int nilfs_segctor_sync(struct nilfs_sc_info *sci)
	return err;
}

static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err)
static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err, bool force)
{
	struct nilfs_segctor_wait_request *wrq, *n;
	unsigned long flags;
@@ -2202,7 +2221,7 @@ static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err)
	spin_lock_irqsave(&sci->sc_wait_request.lock, flags);
	list_for_each_entry_safe(wrq, n, &sci->sc_wait_request.head, wq.entry) {
		if (!atomic_read(&wrq->done) &&
		    nilfs_cnt32_ge(sci->sc_seq_done, wrq->seq)) {
		    (force || nilfs_cnt32_ge(sci->sc_seq_done, wrq->seq))) {
			wrq->err = err;
			atomic_set(&wrq->done, 1);
		}
@@ -2320,9 +2339,20 @@ int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
 */
static void nilfs_segctor_accept(struct nilfs_sc_info *sci)
{
	bool thread_is_alive;

	spin_lock(&sci->sc_state_lock);
	sci->sc_seq_accepted = sci->sc_seq_request;
	thread_is_alive = (bool)sci->sc_task;
	spin_unlock(&sci->sc_state_lock);

	/*
	 * This function does not race with the log writer thread's
	 * termination.  Therefore, deleting sc_timer, which should not be
	 * done after the log writer thread exits, can be done safely outside
	 * the area protected by sc_state_lock.
	 */
	if (thread_is_alive)
		del_timer_sync(&sci->sc_timer);
}

@@ -2340,7 +2370,7 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err)
	if (mode == SC_LSEG_SR) {
		sci->sc_state &= ~NILFS_SEGCTOR_COMMIT;
		sci->sc_seq_done = sci->sc_seq_accepted;
		nilfs_segctor_wakeup(sci, err);
		nilfs_segctor_wakeup(sci, err, false);
		sci->sc_flush_request = 0;
	} else {
		if (mode == SC_FLUSH_FILE)
@@ -2349,7 +2379,7 @@ static void nilfs_segctor_notify(struct nilfs_sc_info *sci, int mode, int err)
			sci->sc_flush_request &= ~FLUSH_DAT_BIT;

		/* re-enable timer if checkpoint creation was not done */
		if ((sci->sc_state & NILFS_SEGCTOR_COMMIT) &&
		if ((sci->sc_state & NILFS_SEGCTOR_COMMIT) && sci->sc_task &&
		    time_before(jiffies, sci->sc_timer.expires))
			add_timer(&sci->sc_timer);
	}
@@ -2539,6 +2569,7 @@ static int nilfs_segctor_thread(void *arg)
	int timeout = 0;

	sci->sc_timer_task = current;
	timer_setup(&sci->sc_timer, nilfs_construction_timeout, 0);

	/* start sync. */
	sci->sc_task = current;
@@ -2606,6 +2637,7 @@ static int nilfs_segctor_thread(void *arg)
 end_thread:
	/* end sync. */
	sci->sc_task = NULL;
	timer_shutdown_sync(&sci->sc_timer);
	wake_up(&sci->sc_wait_task); /* for nilfs_segctor_kill_thread() */
	spin_unlock(&sci->sc_state_lock);
	return 0;
@@ -2669,7 +2701,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb,
	INIT_LIST_HEAD(&sci->sc_gc_inodes);
	INIT_LIST_HEAD(&sci->sc_iput_queue);
	INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func);
	timer_setup(&sci->sc_timer, nilfs_construction_timeout, 0);

	sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
	sci->sc_mjcp_freq = HZ * NILFS_SC_DEFAULT_SR_FREQ;
@@ -2723,6 +2754,13 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
		|| sci->sc_seq_request != sci->sc_seq_done);
	spin_unlock(&sci->sc_state_lock);

	/*
	 * Forcibly wake up tasks waiting in nilfs_segctor_sync(), which can
	 * be called from delayed iput() via nilfs_evict_inode() and can race
	 * with the above log writer thread termination.
	 */
	nilfs_segctor_wakeup(sci, 0, true);

	if (flush_work(&sci->sc_iput_work))
		flag = true;

@@ -2748,7 +2786,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)

	down_write(&nilfs->ns_segctor_sem);

	timer_shutdown_sync(&sci->sc_timer);
	kfree(sci);
}

+7 −2
Original line number Diff line number Diff line
@@ -970,12 +970,17 @@ static int show_smaps_rollup(struct seq_file *m, void *v)
				break;

			/* Case 1 and 2 above */
			if (vma->vm_start >= last_vma_end)
			if (vma->vm_start >= last_vma_end) {
				smap_gather_stats(vma, &mss, 0);
				last_vma_end = vma->vm_end;
				continue;
			}

			/* Case 4 above */
			if (vma->vm_end > last_vma_end)
			if (vma->vm_end > last_vma_end) {
				smap_gather_stats(vma, &mss, last_vma_end);
				last_vma_end = vma->vm_end;
			}
		}
	} for_each_vma(vmi, vma);

Loading