.. | .. |
---|
1614 | 1614 | unsigned long flags; |
---|
1615 | 1615 | int migratetype; |
---|
1616 | 1616 | unsigned long pfn = page_to_pfn(page); |
---|
| 1617 | + bool skip_free_unref_page = false; |
---|
1617 | 1618 | |
---|
1618 | 1619 | if (!free_pages_prepare(page, order, true, fpi_flags)) |
---|
1619 | 1620 | return; |
---|
1620 | 1621 | |
---|
1621 | 1622 | migratetype = get_pfnblock_migratetype(page, pfn); |
---|
| 1623 | + trace_android_vh_free_unref_page_bypass(page, order, migratetype, &skip_free_unref_page); |
---|
| 1624 | + if (skip_free_unref_page) |
---|
| 1625 | + return; |
---|
| 1626 | + |
---|
1622 | 1627 | local_irq_save(flags); |
---|
1623 | 1628 | __count_vm_events(PGFREE, 1 << order); |
---|
1624 | 1629 | free_one_page(page_zone(page), page, pfn, order, migratetype, |
---|
.. | .. |
---|
2797 | 2802 | struct page *page; |
---|
2798 | 2803 | int order; |
---|
2799 | 2804 | bool ret; |
---|
| 2805 | + bool skip_unreserve_highatomic = false; |
---|
2800 | 2806 | |
---|
2801 | 2807 | for_each_zone_zonelist_nodemask(zone, z, zonelist, ac->highest_zoneidx, |
---|
2802 | 2808 | ac->nodemask) { |
---|
.. | .. |
---|
2806 | 2812 | */ |
---|
2807 | 2813 | if (!force && zone->nr_reserved_highatomic <= |
---|
2808 | 2814 | pageblock_nr_pages) |
---|
| 2815 | + continue; |
---|
| 2816 | + |
---|
| 2817 | + trace_android_vh_unreserve_highatomic_bypass(force, zone, |
---|
| 2818 | + &skip_unreserve_highatomic); |
---|
| 2819 | + if (skip_unreserve_highatomic) |
---|
2809 | 2820 | continue; |
---|
2810 | 2821 | |
---|
2811 | 2822 | spin_lock_irqsave(&zone->lock, flags); |
---|
.. | .. |
---|
3053 | 3064 | struct list_head *list = &pcp->lists[migratetype]; |
---|
3054 | 3065 | |
---|
3055 | 3066 | if (list_empty(list)) { |
---|
| 3067 | + trace_android_vh_rmqueue_bulk_bypass(order, pcp, migratetype, list); |
---|
| 3068 | + if (!list_empty(list)) |
---|
| 3069 | + return list; |
---|
| 3070 | + |
---|
3056 | 3071 | pcp->count += rmqueue_bulk(zone, order, |
---|
3057 | 3072 | pcp->batch, list, |
---|
3058 | 3073 | migratetype, alloc_flags); |
---|
.. | .. |
---|
3349 | 3364 | { |
---|
3350 | 3365 | unsigned long flags; |
---|
3351 | 3366 | unsigned long pfn = page_to_pfn(page); |
---|
| 3367 | + int migratetype; |
---|
| 3368 | + bool skip_free_unref_page = false; |
---|
3352 | 3369 | |
---|
3353 | 3370 | if (!free_unref_page_prepare(page, pfn)) |
---|
| 3371 | + return; |
---|
| 3372 | + |
---|
| 3373 | + migratetype = get_pfnblock_migratetype(page, pfn); |
---|
| 3374 | + trace_android_vh_free_unref_page_bypass(page, 0, migratetype, &skip_free_unref_page); |
---|
| 3375 | + if (skip_free_unref_page) |
---|
3354 | 3376 | return; |
---|
3355 | 3377 | |
---|
3356 | 3378 | local_irq_save(flags); |
---|
.. | .. |
---|
4828 | 4850 | unsigned int zonelist_iter_cookie; |
---|
4829 | 4851 | int reserve_flags; |
---|
4830 | 4852 | unsigned long vh_record; |
---|
| 4853 | + bool should_alloc_retry = false; |
---|
4831 | 4854 | |
---|
4832 | 4855 | trace_android_vh_alloc_pages_slowpath_begin(gfp_mask, order, &vh_record); |
---|
4833 | 4856 | /* |
---|
.. | .. |
---|
4967 | 4990 | |
---|
4968 | 4991 | if (page) |
---|
4969 | 4992 | goto got_pg; |
---|
| 4993 | + |
---|
| 4994 | + trace_android_vh_should_alloc_pages_retry(gfp_mask, order, |
---|
| 4995 | + &alloc_flags, ac->migratetype, ac->preferred_zoneref->zone, |
---|
| 4996 | + &page, &should_alloc_retry); |
---|
| 4997 | + if (should_alloc_retry) |
---|
| 4998 | + goto retry; |
---|
4970 | 4999 | |
---|
4971 | 5000 | /* Try direct reclaim and then allocating */ |
---|
4972 | 5001 | page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac, |
---|
.. | .. |
---|
5240 | 5269 | |
---|
5241 | 5270 | void __free_pages(struct page *page, unsigned int order) |
---|
5242 | 5271 | { |
---|
| 5272 | + /* get PageHead before we drop reference */ |
---|
| 5273 | + int head = PageHead(page); |
---|
| 5274 | + |
---|
5243 | 5275 | trace_android_vh_free_pages(page, order); |
---|
5244 | 5276 | if (put_page_testzero(page)) |
---|
5245 | 5277 | free_the_page(page, order); |
---|
5246 | | - else if (!PageHead(page)) |
---|
| 5278 | + else if (!head) |
---|
5247 | 5279 | while (order-- > 0) |
---|
5248 | 5280 | free_the_page(page + (1 << order), order); |
---|
5249 | 5281 | } |
---|
.. | .. |
---|
6158 | 6190 | int nid; |
---|
6159 | 6191 | int __maybe_unused cpu; |
---|
6160 | 6192 | pg_data_t *self = data; |
---|
| 6193 | + unsigned long flags; |
---|
6161 | 6194 | |
---|
| 6195 | + /* |
---|
| 6196 | + * Explicitly disable this CPU's interrupts before taking seqlock |
---|
| 6197 | + * to prevent any IRQ handler from calling into the page allocator |
---|
| 6198 | + * (e.g. GFP_ATOMIC) that could hit zonelist_iter_begin and livelock. |
---|
| 6199 | + */ |
---|
| 6200 | + local_irq_save(flags); |
---|
| 6201 | + /* |
---|
| 6202 | + * Explicitly disable this CPU's synchronous printk() before taking |
---|
| 6203 | + * seqlock to prevent any printk() from trying to hold port->lock, for |
---|
| 6204 | + * tty_insert_flip_string_and_push_buffer() on other CPU might be |
---|
| 6205 | + * calling kmalloc(GFP_ATOMIC | __GFP_NOWARN) with port->lock held. |
---|
| 6206 | + */ |
---|
| 6207 | + printk_deferred_enter(); |
---|
6162 | 6208 | write_seqlock(&zonelist_update_seq); |
---|
6163 | 6209 | |
---|
6164 | 6210 | #ifdef CONFIG_NUMA |
---|
.. | .. |
---|
6193 | 6239 | } |
---|
6194 | 6240 | |
---|
6195 | 6241 | write_sequnlock(&zonelist_update_seq); |
---|
| 6242 | + printk_deferred_exit(); |
---|
| 6243 | + local_irq_restore(flags); |
---|
6196 | 6244 | } |
---|
6197 | 6245 | |
---|
6198 | 6246 | static noinline void __init |
---|
.. | .. |
---|
6612 | 6660 | static void pageset_update(struct per_cpu_pages *pcp, unsigned long high, |
---|
6613 | 6661 | unsigned long batch) |
---|
6614 | 6662 | { |
---|
| 6663 | + trace_android_vh_pageset_update(&high, &batch); |
---|
6615 | 6664 | /* start with a fail safe value for batch */ |
---|
6616 | 6665 | pcp->batch = 1; |
---|
6617 | 6666 | smp_wmb(); |
---|