[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20230201195104.507817318@redhat.com>
Date: Wed, 01 Feb 2023 16:50:18 -0300
From: Marcelo Tosatti <mtosatti@...hat.com>
To: Christoph Lameter <cl@...ux.com>
Cc: Aaron Tomlin <atomlin@...mlin.com>,
Frederic Weisbecker <frederic@...nel.org>,
Andrew Morton <akpm@...ux-foundation.org>,
linux-kernel@...r.kernel.org, linux-mm@...ck.org,
Marcelo Tosatti <mtosatti@...hat.com>
Subject: [PATCH 5/5] mm/vmstat: refresh stats remotely instead of via work item
Refresh per-CPU stats remotely, instead of queueing
work items, for the stat_refresh procfs method.
This fixes sosreport hang (which uses vmstat_refresh) with
spinning SCHED_FIFO process.
Signed-off-by: Marcelo Tosatti <mtosatti@...hat.com>
Index: linux-vmstat-remote/mm/vmstat.c
===================================================================
--- linux-vmstat-remote.orig/mm/vmstat.c
+++ linux-vmstat-remote/mm/vmstat.c
@@ -1865,11 +1865,21 @@ static DEFINE_PER_CPU(struct delayed_wor
int sysctl_stat_interval __read_mostly = HZ;
#ifdef CONFIG_PROC_FS
+
+#ifdef CONFIG_HAVE_CMPXCHG_LOCAL
+static int refresh_all_vm_stats(void);
+#else
static void refresh_vm_stats(struct work_struct *work)
{
refresh_cpu_vm_stats();
}
+static int refresh_all_vm_stats(void)
+{
+ return schedule_on_each_cpu(refresh_vm_stats);
+}
+#endif
+
int vmstat_refresh(struct ctl_table *table, int write,
void *buffer, size_t *lenp, loff_t *ppos)
{
@@ -1889,7 +1899,7 @@ int vmstat_refresh(struct ctl_table *tab
* transiently negative values, report an error here if any of
* the stats is negative, so we know to go looking for imbalance.
*/
- err = schedule_on_each_cpu(refresh_vm_stats);
+ err = refresh_all_vm_stats();
if (err)
return err;
for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
@@ -2009,7 +2019,7 @@ static DECLARE_DEFERRABLE_WORK(shepherd,
#ifdef CONFIG_HAVE_CMPXCHG_LOCAL
/* Flush counters remotely if CPU uses cmpxchg to update its per-CPU counters */
-static void vmstat_shepherd(struct work_struct *w)
+static int refresh_all_vm_stats(void)
{
int cpu;
@@ -2019,7 +2029,12 @@ static void vmstat_shepherd(struct work_
cond_resched();
}
cpus_read_unlock();
+ return 0;
+}
+static void vmstat_shepherd(struct work_struct *w)
+{
+ refresh_all_vm_stats();
schedule_delayed_work(&shepherd,
round_jiffies_relative(sysctl_stat_interval));
}
Powered by blists - more mailing lists