}
 }
 
+void memcg1_commit_charge(struct folio *folio, struct mem_cgroup *memcg)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       memcg1_charge_statistics(memcg, folio_nr_pages(folio));
+       memcg1_check_events(memcg, folio_nid(folio));
+       local_irq_restore(flags);
+}
+
+void memcg1_swapout(struct folio *folio, struct mem_cgroup *memcg)
+{
+       /*
+        * Interrupts should be disabled here because the caller holds the
+        * i_pages lock which is taken with interrupts-off. It is
+        * important here to have the interrupts disabled because it is the
+        * only synchronisation we have for updating the per-CPU variables.
+        */
+       preempt_disable_nested();
+       VM_WARN_ON_IRQS_ENABLED();
+       memcg1_charge_statistics(memcg, -folio_nr_pages(folio));
+       preempt_enable_nested();
+       memcg1_check_events(memcg, folio_nid(folio));
+}
+
+void memcg1_uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout,
+                          unsigned long nr_memory, int nid)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       __count_memcg_events(memcg, PGPGOUT, pgpgout);
+       __this_cpu_add(memcg->events_percpu->nr_page_events, nr_memory);
+       memcg1_check_events(memcg, nid);
+       local_irq_restore(flags);
+}
+
 static int compare_thresholds(const void *a, const void *b)
 {
        const struct mem_cgroup_threshold *_a = a;
 
 void memcg1_charge_statistics(struct mem_cgroup *memcg, int nr_pages);
 void memcg1_check_events(struct mem_cgroup *memcg, int nid);
 
+void memcg1_commit_charge(struct folio *folio, struct mem_cgroup *memcg);
+void memcg1_swapout(struct folio *folio, struct mem_cgroup *memcg);
+void memcg1_uncharge_batch(struct mem_cgroup *memcg, unsigned long pgpgout,
+                          unsigned long nr_memory, int nid);
+
 void memcg1_stat_format(struct mem_cgroup *memcg, struct seq_buf *s);
 
 void memcg1_account_kmem(struct mem_cgroup *memcg, int nr_pages);
 static inline void memcg1_charge_statistics(struct mem_cgroup *memcg, int nr_pages) {}
 static inline void memcg1_check_events(struct mem_cgroup *memcg, int nid) {}
 
+static inline void memcg1_commit_charge(struct folio *folio,
+                                       struct mem_cgroup *memcg) {}
+
+static inline void memcg1_swapout(struct folio *folio, struct mem_cgroup *memcg) {}
+
+static inline void memcg1_uncharge_batch(struct mem_cgroup *memcg,
+                                        unsigned long pgpgout,
+                                        unsigned long nr_memory, int nid) {}
+
 static inline void memcg1_stat_format(struct mem_cgroup *memcg, struct seq_buf *s) {}
 
 static inline void memcg1_account_kmem(struct mem_cgroup *memcg, int nr_pages) {}
 
 {
        css_get(&memcg->css);
        commit_charge(folio, memcg);
-
-       local_irq_disable();
-       memcg1_charge_statistics(memcg, folio_nr_pages(folio));
-       memcg1_check_events(memcg, folio_nid(folio));
-       local_irq_enable();
+       memcg1_commit_charge(folio, memcg);
 }
 
 static inline void __mod_objcg_mlstate(struct obj_cgroup *objcg,
 
 static void uncharge_batch(const struct uncharge_gather *ug)
 {
-       unsigned long flags;
-
        if (ug->nr_memory) {
                page_counter_uncharge(&ug->memcg->memory, ug->nr_memory);
                if (do_memsw_account())
                memcg1_oom_recover(ug->memcg);
        }
 
-       local_irq_save(flags);
-       __count_memcg_events(ug->memcg, PGPGOUT, ug->pgpgout);
-       __this_cpu_add(ug->memcg->events_percpu->nr_page_events, ug->nr_memory);
-       memcg1_check_events(ug->memcg, ug->nid);
-       local_irq_restore(flags);
+       memcg1_uncharge_batch(ug->memcg, ug->pgpgout, ug->nr_memory, ug->nid);
 
        /* drop reference from uncharge_folio */
        css_put(&ug->memcg->css);
 {
        struct mem_cgroup *memcg;
        long nr_pages = folio_nr_pages(new);
-       unsigned long flags;
 
        VM_BUG_ON_FOLIO(!folio_test_locked(old), old);
        VM_BUG_ON_FOLIO(!folio_test_locked(new), new);
 
        css_get(&memcg->css);
        commit_charge(new, memcg);
-
-       local_irq_save(flags);
-       memcg1_charge_statistics(memcg, nr_pages);
-       memcg1_check_events(memcg, folio_nid(new));
-       local_irq_restore(flags);
+       memcg1_commit_charge(new, memcg);
 }
 
 /**
                page_counter_uncharge(&memcg->memsw, nr_entries);
        }
 
-       /*
-        * Interrupts should be disabled here because the caller holds the
-        * i_pages lock which is taken with interrupts-off. It is
-        * important here to have the interrupts disabled because it is the
-        * only synchronisation we have for updating the per-CPU variables.
-        */
-       memcg_stats_lock();
-       memcg1_charge_statistics(memcg, -nr_entries);
-       memcg_stats_unlock();
-       memcg1_check_events(memcg, folio_nid(folio));
-
+       memcg1_swapout(folio, memcg);
        css_put(&memcg->css);
 }