aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/memcontrol.c73
1 files changed, 35 insertions, 38 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 42174612cc0b..abb66a2cba65 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -748,37 +748,32 @@ static unsigned long mem_cgroup_nr_lru_pages(struct mem_cgroup *memcg,
748 return total; 748 return total;
749} 749}
750 750
751static bool __memcg_event_check(struct mem_cgroup *memcg, int target) 751static bool mem_cgroup_event_ratelimit(struct mem_cgroup *memcg,
752 enum mem_cgroup_events_target target)
752{ 753{
753 unsigned long val, next; 754 unsigned long val, next;
754 755
755 val = __this_cpu_read(memcg->stat->events[MEM_CGROUP_EVENTS_COUNT]); 756 val = __this_cpu_read(memcg->stat->events[MEM_CGROUP_EVENTS_COUNT]);
756 next = __this_cpu_read(memcg->stat->targets[target]); 757 next = __this_cpu_read(memcg->stat->targets[target]);
757 /* from time_after() in jiffies.h */ 758 /* from time_after() in jiffies.h */
758 return ((long)next - (long)val < 0); 759 if ((long)next - (long)val < 0) {
759} 760 switch (target) {
760 761 case MEM_CGROUP_TARGET_THRESH:
761static void __mem_cgroup_target_update(struct mem_cgroup *memcg, int target) 762 next = val + THRESHOLDS_EVENTS_TARGET;
762{ 763 break;
763 unsigned long val, next; 764 case MEM_CGROUP_TARGET_SOFTLIMIT:
764 765 next = val + SOFTLIMIT_EVENTS_TARGET;
765 val = __this_cpu_read(memcg->stat->events[MEM_CGROUP_EVENTS_COUNT]); 766 break;
766 767 case MEM_CGROUP_TARGET_NUMAINFO:
767 switch (target) { 768 next = val + NUMAINFO_EVENTS_TARGET;
768 case MEM_CGROUP_TARGET_THRESH: 769 break;
769 next = val + THRESHOLDS_EVENTS_TARGET; 770 default:
770 break; 771 break;
771 case MEM_CGROUP_TARGET_SOFTLIMIT: 772 }
772 next = val + SOFTLIMIT_EVENTS_TARGET; 773 __this_cpu_write(memcg->stat->targets[target], next);
773 break; 774 return true;
774 case MEM_CGROUP_TARGET_NUMAINFO:
775 next = val + NUMAINFO_EVENTS_TARGET;
776 break;
777 default:
778 return;
779 } 775 }
780 776 return false;
781 __this_cpu_write(memcg->stat->targets[target], next);
782} 777}
783 778
784/* 779/*
@@ -789,25 +784,27 @@ static void memcg_check_events(struct mem_cgroup *memcg, struct page *page)
789{ 784{
790 preempt_disable(); 785 preempt_disable();
791 /* threshold event is triggered in finer grain than soft limit */ 786 /* threshold event is triggered in finer grain than soft limit */
792 if (unlikely(__memcg_event_check(memcg, MEM_CGROUP_TARGET_THRESH))) { 787 if (unlikely(mem_cgroup_event_ratelimit(memcg,
788 MEM_CGROUP_TARGET_THRESH))) {
789 bool do_softlimit, do_numainfo;
790
791 do_softlimit = mem_cgroup_event_ratelimit(memcg,
792 MEM_CGROUP_TARGET_SOFTLIMIT);
793#if MAX_NUMNODES > 1
794 do_numainfo = mem_cgroup_event_ratelimit(memcg,
795 MEM_CGROUP_TARGET_NUMAINFO);
796#endif
797 preempt_enable();
798
793 mem_cgroup_threshold(memcg); 799 mem_cgroup_threshold(memcg);
794 __mem_cgroup_target_update(memcg, MEM_CGROUP_TARGET_THRESH); 800 if (unlikely(do_softlimit))
795 if (unlikely(__memcg_event_check(memcg,
796 MEM_CGROUP_TARGET_SOFTLIMIT))) {
797 mem_cgroup_update_tree(memcg, page); 801 mem_cgroup_update_tree(memcg, page);
798 __mem_cgroup_target_update(memcg,
799 MEM_CGROUP_TARGET_SOFTLIMIT);
800 }
801#if MAX_NUMNODES > 1 802#if MAX_NUMNODES > 1
802 if (unlikely(__memcg_event_check(memcg, 803 if (unlikely(do_numainfo))
803 MEM_CGROUP_TARGET_NUMAINFO))) {
804 atomic_inc(&memcg->numainfo_events); 804 atomic_inc(&memcg->numainfo_events);
805 __mem_cgroup_target_update(memcg,
806 MEM_CGROUP_TARGET_NUMAINFO);
807 }
808#endif 805#endif
809 } 806 } else
810 preempt_enable(); 807 preempt_enable();
811} 808}
812 809
813struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) 810struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)