aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slub.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c96
1 files changed, 81 insertions, 15 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 3e614c1901b7..ae2831027802 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1586,13 +1586,16 @@ static int calculate_order(int size)
1586 order < MAX_ORDER; order++) { 1586 order < MAX_ORDER; order++) {
1587 unsigned long slab_size = PAGE_SIZE << order; 1587 unsigned long slab_size = PAGE_SIZE << order;
1588 1588
1589 if (slub_max_order > order && 1589 if (order < slub_max_order &&
1590 slab_size < slub_min_objects * size) 1590 slab_size < slub_min_objects * size)
1591 continue; 1591 continue;
1592 1592
1593 if (slab_size < size) 1593 if (slab_size < size)
1594 continue; 1594 continue;
1595 1595
1596 if (order >= slub_max_order)
1597 break;
1598
1596 rem = slab_size % size; 1599 rem = slab_size % size;
1597 1600
1598 if (rem <= slab_size / 8) 1601 if (rem <= slab_size / 8)
@@ -2751,6 +2754,13 @@ static void resiliency_test(void) {};
2751struct location { 2754struct location {
2752 unsigned long count; 2755 unsigned long count;
2753 void *addr; 2756 void *addr;
2757 long long sum_time;
2758 long min_time;
2759 long max_time;
2760 long min_pid;
2761 long max_pid;
2762 cpumask_t cpus;
2763 nodemask_t nodes;
2754}; 2764};
2755 2765
2756struct loc_track { 2766struct loc_track {
@@ -2791,11 +2801,12 @@ static int alloc_loc_track(struct loc_track *t, unsigned long max)
2791} 2801}
2792 2802
2793static int add_location(struct loc_track *t, struct kmem_cache *s, 2803static int add_location(struct loc_track *t, struct kmem_cache *s,
2794 void *addr) 2804 const struct track *track)
2795{ 2805{
2796 long start, end, pos; 2806 long start, end, pos;
2797 struct location *l; 2807 struct location *l;
2798 void *caddr; 2808 void *caddr;
2809 unsigned long age = jiffies - track->when;
2799 2810
2800 start = -1; 2811 start = -1;
2801 end = t->count; 2812 end = t->count;
@@ -2811,12 +2822,29 @@ static int add_location(struct loc_track *t, struct kmem_cache *s,
2811 break; 2822 break;
2812 2823
2813 caddr = t->loc[pos].addr; 2824 caddr = t->loc[pos].addr;
2814 if (addr == caddr) { 2825 if (track->addr == caddr) {
2815 t->loc[pos].count++; 2826
2827 l = &t->loc[pos];
2828 l->count++;
2829 if (track->when) {
2830 l->sum_time += age;
2831 if (age < l->min_time)
2832 l->min_time = age;
2833 if (age > l->max_time)
2834 l->max_time = age;
2835
2836 if (track->pid < l->min_pid)
2837 l->min_pid = track->pid;
2838 if (track->pid > l->max_pid)
2839 l->max_pid = track->pid;
2840
2841 cpu_set(track->cpu, l->cpus);
2842 }
2843 node_set(page_to_nid(virt_to_page(track)), l->nodes);
2816 return 1; 2844 return 1;
2817 } 2845 }
2818 2846
2819 if (addr < caddr) 2847 if (track->addr < caddr)
2820 end = pos; 2848 end = pos;
2821 else 2849 else
2822 start = pos; 2850 start = pos;
@@ -2834,7 +2862,16 @@ static int add_location(struct loc_track *t, struct kmem_cache *s,
2834 (t->count - pos) * sizeof(struct location)); 2862 (t->count - pos) * sizeof(struct location));
2835 t->count++; 2863 t->count++;
2836 l->count = 1; 2864 l->count = 1;
2837 l->addr = addr; 2865 l->addr = track->addr;
2866 l->sum_time = age;
2867 l->min_time = age;
2868 l->max_time = age;
2869 l->min_pid = track->pid;
2870 l->max_pid = track->pid;
2871 cpus_clear(l->cpus);
2872 cpu_set(track->cpu, l->cpus);
2873 nodes_clear(l->nodes);
2874 node_set(page_to_nid(virt_to_page(track)), l->nodes);
2838 return 1; 2875 return 1;
2839} 2876}
2840 2877
@@ -2850,11 +2887,8 @@ static void process_slab(struct loc_track *t, struct kmem_cache *s,
2850 set_bit(slab_index(p, s, addr), map); 2887 set_bit(slab_index(p, s, addr), map);
2851 2888
2852 for_each_object(p, s, addr) 2889 for_each_object(p, s, addr)
2853 if (!test_bit(slab_index(p, s, addr), map)) { 2890 if (!test_bit(slab_index(p, s, addr), map))
2854 void *addr = get_track(s, p, alloc)->addr; 2891 add_location(t, s, get_track(s, p, alloc));
2855
2856 add_location(t, s, addr);
2857 }
2858} 2892}
2859 2893
2860static int list_locations(struct kmem_cache *s, char *buf, 2894static int list_locations(struct kmem_cache *s, char *buf,
@@ -2888,15 +2922,47 @@ static int list_locations(struct kmem_cache *s, char *buf,
2888 } 2922 }
2889 2923
2890 for (i = 0; i < t.count; i++) { 2924 for (i = 0; i < t.count; i++) {
2891 void *addr = t.loc[i].addr; 2925 struct location *l = &t.loc[i];
2892 2926
2893 if (n > PAGE_SIZE - 100) 2927 if (n > PAGE_SIZE - 100)
2894 break; 2928 break;
2895 n += sprintf(buf + n, "%7ld ", t.loc[i].count); 2929 n += sprintf(buf + n, "%7ld ", l->count);
2896 if (addr) 2930
2897 n += sprint_symbol(buf + n, (unsigned long)t.loc[i].addr); 2931 if (l->addr)
2932 n += sprint_symbol(buf + n, (unsigned long)l->addr);
2898 else 2933 else
2899 n += sprintf(buf + n, "<not-available>"); 2934 n += sprintf(buf + n, "<not-available>");
2935
2936 if (l->sum_time != l->min_time) {
2937 unsigned long remainder;
2938
2939 n += sprintf(buf + n, " age=%ld/%ld/%ld",
2940 l->min_time,
2941 div_long_long_rem(l->sum_time, l->count, &remainder),
2942 l->max_time);
2943 } else
2944 n += sprintf(buf + n, " age=%ld",
2945 l->min_time);
2946
2947 if (l->min_pid != l->max_pid)
2948 n += sprintf(buf + n, " pid=%ld-%ld",
2949 l->min_pid, l->max_pid);
2950 else
2951 n += sprintf(buf + n, " pid=%ld",
2952 l->min_pid);
2953
2954 if (num_online_cpus() > 1 && !cpus_empty(l->cpus)) {
2955 n += sprintf(buf + n, " cpus=");
2956 n += cpulist_scnprintf(buf + n, PAGE_SIZE - n - 50,
2957 l->cpus);
2958 }
2959
2960 if (num_online_nodes() > 1 && !nodes_empty(l->nodes)) {
2961 n += sprintf(buf + n, " nodes=");
2962 n += nodelist_scnprintf(buf + n, PAGE_SIZE - n - 50,
2963 l->nodes);
2964 }
2965
2900 n += sprintf(buf + n, "\n"); 2966 n += sprintf(buf + n, "\n");
2901 } 2967 }
2902 2968