mm: Implement Swap Prefetching v23
Subsystems (8)
PATCH 1/1 mm: Implement Swap Prefetching v23
Here's a respin with Nick's suggestions and a modification to not cost us extra slab on non-numa. Andrew if it's ok I'd like to see this one get a run in -mm. Numa remains compile tested only.
Cheers,
Con
---
This patch implements swap prefetching when the vm is relatively idle and there is free ram available. The code is based on some early work by Thomas Schlichter.
This stores a list of swapped entries in a list ordered most recently used and a radix tree. It generates a low priority kernel thread running at nice 19 to do the prefetching at a later stage.
Once pages have been added to the swapped list, a timer is started, testing for conditions suitable to prefetch swap pages every 5 seconds. Suitable conditions are defined as lack of swapping out or in any pages, and no watermark tests failing. Significant amounts of dirtied ram and changes in free ram representing disk writes or reads also prevent prefetching.
It then checks that we have spare ram looking for at least 3* pages_high free per zone and if it succeeds that will prefetch pages from swap into the swap cache. Pages are prefetched until the list is empty or the vm is seen as busy according to the previously described criteria. Node data on numa is stored with the entries and an appropriate zonelist based on this is used when allocating ram.
The pages are copied to swap cache and kept on backing store. This allows pressure on either physical ram or swap to readily find free pages without further I/O.
Prefetching can be enabled/disabled via the tunable in /proc/sys/vm/swap_prefetch initially set to 1 (enabled).
In testing on modern pc hardware this results in wall-clock time activation of the firefox browser to speed up 5 fold after a worst case complete swap-out of the browser on a static web page.
Documentation/sysctl/vm.txt | 11 + include/linux/swap.h | 54 +++++ include/linux/sysctl.h | 1 init/Kconfig | 22 ++ kernel/sysctl.c | 10 mm/Makefile | 1 mm/page_alloc.c | 1 mm/swap.c | 3 mm/swap_prefetch.c | 473 ++++++++++++++++++++++++++++++++++++++++++++ mm/swap_state.c | 10 mm/vmscan.c | 5 11 files changed, 590 insertions(+), 1 deletion(-)
Documentation/sysctl/vm.txt +11 -0
@@ -29,6 +29,7 @@ Currently, these files are in /proc/sys/ - drop-caches - zone_reclaim_mode - zone_reclaim_interval +- swap_prefetch ==============================================================
@@ -178,3 +179,13 @@ Time is set in seconds and set by defaul Reduce the interval if undesired off node allocations occur. However, too frequent scans will have a negative impact onoff node allocation performance. +============================================================== + +swap_prefetch + +This enables or disables the swap prefetching feature. When the virtual +memory subsystem has been extremely idle for at least 5 seconds it will start +copying back pages from swap into the swapcache and keep a copy in swap. In +practice it can take many minutes before the vm is idle enough. + +The default value is 1.
include/linux/swap.h +54 -0
72 lines not on this page · raw message
include/linux/sysctl.h +1 -0
@@ -184,6 +184,7 @@ enumVM_PERCPU_PAGELIST_FRACTION =30 ,/* int: fraction of pages in each percpu_pagelist */ VM_ZONE_RECLAIM_MODE =31 ,/* reclaim local zone memory before going off node */ VM_ZONE_RECLAIM_INTERVAL =32 ,/* time period to wait after reclaim failure */ + VM_SWAP_PREFETCH=33, /* swap prefetch */ };
init/Kconfig +22 -0
@@ -103,6 +103,28 @@ config SWAP used to provide more virtual memory than the actual RAM present in your computer. If unsure say Y. +config SWAP_PREFETCH + bool "Support for prefetching swapped memory" + depends on SWAP + default y + ---help--- + This option will allow the kernel to prefetch swapped memory pages + when idle. The pages will be kept on both swap and in swap_cache + thus avoiding the need for further I/O if either ram or swap space + is required. + + What this will do on workstations is slowly bring back applications + that have swapped out after memory intensive workloads back into + physical ram if you have free ram at a later stage and the machine + is relatively idle. This means that when you come back to your + computer after leaving it idle for a while, applications will come + to life faster. Note that your swap usage will appear to increase + but these are cached pages, can be dropped freely by the vm, and it + should stabilise around 50% swap usage maximum. + + Workstations and multiuser workstation servers will most likely want + to say Y. + config SYSVIPC bool "System V IPC" ---help---
kernel/sysctl.c +10 -0
@@ -891,6 +891,16 @@ static ctl_table vm_table[] = { .strategy = &sysctl_jiffies, },#endif +#ifdef CONFIG_SWAP_PREFETCH + { + .ctl_name = VM_SWAP_PREFETCH, + .procname = "swap_prefetch", + .data = &swap_prefetch, + .maxlen = sizeof(swap_prefetch), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, +#endif { .ctl_name = 0 } };
mm/Makefile +1 -0
@@ -13,6 +13,7 @@ obj-y := bootmem.o filemap.o mempool.o prio_tree.o util.o $(mmu-y) obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o +obj-$(CONFIG_SWAP_PREFETCH) += swap_prefetch.o obj-$(CONFIG_HUGETLBFS) += hugetlb.o obj-$(CONFIG_NUMA) += mempolicy.o obj-$(CONFIG_SPARSEMEM) += sparse.o
mm/page_alloc.c +1 -0
@@ -844,6 +844,7 @@ int zone_watermark_ok(struct zone *z, inif (free_pages <= min)return 0 ; } +return 1 ; }
mm/swap.c +3 -0
@@ -502,5 +502,8 @@ void __init swap_setup(void)* Right now other parts of the system means that we * _really_ don't want to cluster much more */ + +prepare_swap_prefetch (); +hotcpu_notifier (cpu_swap_callback,0 ); }
mm/swap_prefetch.c new file +473 -0
473 lines not on this page · raw message
mm/swap_state.c +9 -1
@@ -81,6 +81,7 @@ static int __add_to_swap_cache(struct pa error =radix_tree_insert (&swapper_space.page_tree, entry.val, page);if (!error) { +remove_from_swapped_list (entry.val);page_cache_get (page);SetPageLocked (page);SetPageSwapCache (page);
@@ -94,11 +95,12 @@ static int __add_to_swap_cache(struct pareturn error; } -static int add_to_swap_cache (struct page *page,swp_entry_t entry) +int add_to_swap_cache (struct page *page,swp_entry_t entry) {int error;if (!swap_duplicate (entry)) { +remove_from_swapped_list (entry.val);INC_CACHE_INFO (noent_race);return -ENOENT ; }
@@ -147,6 +149,9 @@ int add_to_swap(struct page * page, gfp_swp_entry_t entry;int err; +/* Swap prefetching is delayed if we're swapping pages */ +delay_swap_prefetch (); +if (!PageLocked (page))BUG ();
@@ -320,6 +325,9 @@ struct page *read_swap_cache_async(swp_estruct page *found_page, *new_page =NULL ;int err; +/* Swap prefetching is delayed if we're already reading from swap */ +delay_swap_prefetch (); + do { /* * First check the swap cache. Since this is normally
mm/vmscan.c +5 -0
@@ -396,6 +396,7 @@ static int remove_mapping(struct addressif (PageSwapCache (page)) {swp_entry_t swap = { .val =page_private (page) }; +add_to_swapped_list (page);__delete_from_swap_cache (page);write_unlock_irq (&mapping->tree_lock);swap_free (swap);
@@ -1406,6 +1407,8 @@ int try_to_free_pages(struct zone **zoneunsigned long lru_pages =0 ;int i; +delay_swap_prefetch (); + sc.gfp_mask = gfp_mask; sc.may_writepage = !laptop_mode; sc.may_swap =1 ;
@@ -1758,6 +1761,8 @@ int shrink_all_memory(int nr_pages) .reclaimed_slab = 0, }; +delay_swap_prefetch (); + current->reclaim_state = &reclaim_state;for_each_pgdat (pgdat) {int freed;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 3 lines · Con Kolivas
Here's a respin with Nick's suggestions and a modification to not cost us extra slab on non-numa.
v23? I'm sure we can do better than that.
Quoted 1 line
Andrew if it's ok I'd like to see this one get a run in -mm.
hm.
Quoted 2 lines
This patch implements swap prefetching when the vm is relatively idle and there is free ram available.
I think "free ram available" is the critical thing here. If it doesn't evict anyhing else then OK, it basically uses unutilised disk bandwidth for free.
But where does it put the pages? If it was really "free", they'd go onto the tail of the inactive list.
And what about all those unpaged text pages which the app will need to fault back in?
Quoted 5 lines
Once pages have been added to the swapped list, a timer is started, testing for conditions suitable to prefetch swap pages every 5 seconds. Suitable conditions are defined as lack of swapping out or in any pages, and no watermark tests failing. Significant amounts of dirtied ram and changes in free ram representing disk writes or reads also prevent prefetching.
OK. The has-the-disk-been-used-recently test still isn't there?
mm/page_alloc.c int zone_watermark_ok(struct zone *z, in · line 849
Quoted 7 lines
mm/page_alloc.c +1
-0@@ -844,6 +844,7 @@ int zone_watermark_ok(struct zone *z, inif (free_pages <= min)return 0 ; } +return 1 ; }
?
mm/swap_prefetch.c line 175
Quoted 1 line
mm/swap_prefetch.c new file +1
-0+read_lock (&swapper_space.tree_lock);
That's interesting. We conventionally do read_lock_irq() on an address_space.tree_lock. Because end_page_writeback()->rotate_reclaimable_page()->test_clear_page_writeback() needs to take a write_lock from interrupt context. end_swap_bio_write() calls end_page_writeback() so I don't immediately see why we don't have a deadlock here.
Ordinarily we'd just use find_get_page(), but
mm/swap_prefetch.c line 182
Quoted 7 lines
mm/swap_prefetch.c new file +7
-0+/* Entry may already exist */ + page =radix_tree_lookup (&swapper_space.page_tree, entry.val); +read_unlock (&swapper_space.tree_lock); +if (page) { +remove_from_swapped_list (entry.val); + goto out; + }
you don't take a ref on the page.
Which makes one wonder what happens here if `page' got whipped out of swapcache between the lookup and the remove_from_swapped_list(). Probably nothing much.
Did you consider borrowing swapper_space.tree_lock to provide the list and radix-tree locking throughout here?
mm/swap_prefetch.c line 402
Quoted 6 lines
mm/swap_prefetch.c new file +6
-0+out: +if (mru) { +spin_lock (&swapped.lock); + swapped.list.next = mru; +spin_unlock (&swapped.lock); + }
That looks strange. What happens to swapped.list.prev?
Quoted 5 lines
mm/swap_prefetch.c new file +5
-0+static int kprefetchd (void *__unused) +{ +set_user_nice (current,19 ); +/* Set ioprio to lowest if supported by i/o scheduler */ +sys_ioprio_set (IOPRIO_WHO_PROCESS ,0 ,IOPRIO_CLASS_IDLE );
mm/swap_prefetch.c line 424
Quoted 10 lines
mm/swap_prefetch.c new file +10
-0+ + do { + try_to_freeze(); + + /* + * TRICKLE_FAILED implies no entries left - we do not schedule + * a wakeup, and further delay the next one. + */ + if (trickle_swap() == TRICKLE_FAILED) + schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
set_current_state(TASK_INTERRUPTIBLE); schedule();
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 5 lines · Andrew Morton
Quoted 2 lines · Con Kolivas
Here's a respin with Nick's suggestions and a modification to not cost us extra slab on non-numa.
v23? I'm sure we can do better than that.
:D
Quoted 9 lines
Quoted 2 lines
This patch implements swap prefetching when the vm is relatively idle and there is free ram available.
I think "free ram available" is the critical thing here. If it doesn't evict anyhing else then OK, it basically uses unutilised disk bandwidth for free.
But where does it put the pages? If it was really "free", they'd go onto the tail of the inactive list.
It puts them in swapcache. This seems to work nicely as a nowhere-land place where they don't have much affect on anything until we need them or need more ram. This has worked well, but I'm open to other suggestions.
Quoted 2 lines
And what about all those unpaged text pages which the app will need to fault back in?
Tracking these would make the perceived time to wakeup much much faster but also make the list a heck of a lot larger.. but more to the point I have no idea how to do it and get what we really want on the list.
Quoted 8 lines
Quoted 6 lines
Once pages have been added to the swapped list, a timer is started, testing for conditions suitable to prefetch swap pages every 5 seconds. Suitable conditions are defined as lack of swapping out or in any pages, and no watermark tests failing. Significant amounts of dirtied ram and changes in free ram representing disk writes or reads also prevent prefetching.
OK. The has-the-disk-been-used-recently test still isn't there?
No, but you'd have to free up +/- SWAP_SCAN_MAX as many pages as you fill when reading from disk for this indirect method to not pick it up. It's easy enough to see that it's effective: You can sit and watch vmstat for many minutes after say an oom-kill in the hope you see it quiet enough before prefetch does anything. After allowing 'tail -f /dev/zero' to be oomkilled in a full gui environment it usually takes >5 mins before swap prefetch starts prefetching.
Quoted 9 lines
mm/page_alloc.c int zone_watermark_ok(struct zone *z, in · line 849
Quoted 7 lines
mm/page_alloc.c +1
-0@@ -844,6 +844,7 @@ int zone_watermark_ok(struct zone *z, inif (free_pages <= min)return 0 ; } +return 1 ; }?
Legacy of v1->v22..
Quoted 9 lines
mm/swap_prefetch.c line 175
Quoted 2 lines
mm/swap_prefetch.c new file +1
-0+read_lock (&swapper_space.tree_lock);That's interesting. We conventionally do
read_lock_irq()on an address_space.tree_lock. Because end_page_writeback()->rotate_reclaimable_page()->test_clear_page_writeback( ) needs to take awrite_lockfrom interrupt context.end_swap_bio_write()callsend_page_writeback()so I don't immediately see why we don't have a deadlock here.
Wasn't sure of the semantics. I was lucky I guess.
Quoted 12 lines
Ordinarily we'd just use
find_get_page(), butmm/swap_prefetch.c line 182
Quoted 7 lines
mm/swap_prefetch.c new file +7
-0+/* Entry may already exist */ + page =radix_tree_lookup (&swapper_space.page_tree, entry.val); +read_unlock (&swapper_space.tree_lock); +if (page) { +remove_from_swapped_list (entry.val); + goto out; + }you don't take a ref on the page.
Quoted 6 lines
Which makes one wonder what happens here if `page' got whipped out of swapcache between the lookup and the
remove_from_swapped_list(). Probably nothing much.Did you consider borrowing swapper_space.tree_lock to provide the list and radix-tree locking throughout here?
I did. I was concerned that since most of the functions occur as we swap in or out that we'd end up with more contention of that lock.
Quoted 8 lines
mm/swap_prefetch.c line 402
Quoted 6 lines
mm/swap_prefetch.c new file +6
-0+out: +if (mru) { +spin_lock (&swapped.lock); + swapped.list.next = mru; +spin_unlock (&swapped.lock); + }That looks strange. What happens to swapped.list.prev?
Left dangling for future null dereferencing... Only would have been hit on numa.
Quoted 4 lines
mm/swap_prefetch.c line 424
Quoted 1 line
mm/swap_prefetch.c new file +1
-0+schedule_timeout_interruptible (MAX_SCHEDULE_TIMEOUT );set_current_state(TASK_INTERRUPTIBLE); schedule();
Ack.
Thanks! I guess I will be working on v24 in the near future...
Cheers,
Con
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 20 lines · Con Kolivas
Quoted 6 lines · Andrew Morton
Quoted 2 lines · Con Kolivas
Here's a respin with Nick's suggestions and a modification to not cost us extra slab on non-numa.
v23? I'm sure we can do better than that.
:D
Quoted 7 lines
Quoted 2 lines
This patch implements swap prefetching when the vm is relatively idle and there is free ram available.
I think "free ram available" is the critical thing here. If it doesn't evict anyhing else then OK, it basically uses unutilised disk bandwidth for free.
Quoted 6 lines
Quoted 2 lines
But where does it put the pages? If it was really "free", they'd go onto the tail of the inactive list.
It puts them in swapcache. This seems to work nicely as a nowhere-land place where they don't have much affect on anything until we need them or need more ram. This has worked well, but I'm open to other suggestions.
Well they go on the head of the inactive list and will kick out file backed pagecache. Which was my concern about reducing the usefulness of useful swapping on desktop systems.
Signature · 8 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 5 lines · Nick Piggin
Quoted 4 lines · Con Kolivas
Quoted 2 lines · Andrew Morton
But where does it put the pages? If it was really "free", they'd go onto the tail of the inactive list.
Quoted 7 lines
Quoted 3 lines
It puts them in swapcache. This seems to work nicely as a nowhere-land place where they don't have much affect on anything until we need them or need more ram. This has worked well, but I'm open to other suggestions.
Well they go on the head of the inactive list and will kick out file backed pagecache. Which was my concern about reducing the usefulness of useful swapping on desktop systems.
Ok I see. We don't have a way to add to the tail of that list though? Is that a worthwhile addition to this (ever growing) project? That would definitely have an impact on the other code if not all done within swap_prefetch.c.. which would also be quite a large open coded something.
Cheers,
Con
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 8 lines · Con Kolivas
Quoted 3 lines · Nick Piggin
Well they go on the head of the inactive list and will kick out file backed pagecache. Which was my concern about reducing the usefulness of useful swapping on desktop systems.
Ok I see. We don't have a way to add to the tail of that list though? Is that a worthwhile addition to this (ever growing) project? That would definitely
Don't know, can you tell us?
Signature · 8 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 2 lines · Con Kolivas
Ok I see. We don't have a way to add to the tail of that list though?
del_page_from_lru() + (new) add_page_to_inactive_list_tail().
Quoted 4 lines
Is that
a worthwhile addition to this (ever growing) project? That would definitely have an impact on the other code if not all done withinswap_prefetch.c.. which would also be quite a large open coded something.
Do both of the above in a new function in swap.c.
It's likely to have quite some impact on the overall behaviour of the feature - would need careful testing. It might end up screwing the whole thing up.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 5 lines · Andrew Morton
Quoted 1 line · Con Kolivas
Ok I see. We don't have a way to add to the tail of that list though?
Quoted 8 lines
del_page_from_lru()+ (new)add_page_to_inactive_list_tail().Quoted 1 line
Is that a worthwhile addition to this (ever growing) project? That would definitely have an impact on the other code if not all done within
swap_prefetch.c.. which would also be quite a large open coded something.Do both of the above in a new function in
swap.c.
That'll require the caller to do lru locking.
I'd add an lru_cache_add_tail, use it instead of the current lru_cache_add that Con's got now, and just implement it in a simple manner, without pagevecs.
Signature · 8 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 16 lines · Nick Piggin
Quoted 14 lines · Andrew Morton
Quoted 1 line · Con Kolivas
Ok I see. We don't have a way to add to the tail of that list though?
del_page_from_lru()+ (new)add_page_to_inactive_list_tail().Quoted 4 lines
Is that
a worthwhile addition to this (ever growing) project? That would definitely have an impact on the other code if not all done withinswap_prefetch.c.. which would also be quite a large open coded something.
Quoted 8 lines
Quoted 2 lines
Do both of the above in a new function in
swap.c.That'll require the caller to do lru locking.
I'd add an
lru_cache_add_tail, use it instead of the currentlru_cache_addthat Con's got now, and just implement it in a simple manner, without pagevecs.
umm, that's what I said ;)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 20 lines · Andrew Morton
Quoted 18 lines · Nick Piggin
Quoted 15 lines · Andrew Morton
Quoted 1 line · Con Kolivas
Ok I see. We don't have a way to add to the tail of that list though?
del_page_from_lru()+ (new)add_page_to_inactive_list_tail().Quoted 1 line
Is that a worthwhile addition to this (ever growing) project? That would definitely have an impact on the other code if not all done within
swap_prefetch.c.. which would also be quite a large open coded something.Do both of the above in a new function in
swap.c.
Quoted 9 lines
Quoted 5 lines
That'll require the caller to do lru locking.
I'd add an
lru_cache_add_tail, use it instead of the currentlru_cache_addthat Con's got now, and just implement it in a simple manner, without pagevecs.umm, that's what I said ;)
You said del_page_from_lru(), which doesn't belong in a function called lru_cache_add_tail.
Signature · 8 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 18 lines · Nick Piggin
Quoted 17 lines · Andrew Morton
Quoted 16 lines · Nick Piggin
Quoted 5 lines · Andrew Morton
Quoted 1 line · Con Kolivas
Ok I see. We don't have a way to add to the tail of that list though?
del_page_from_lru()+ (new)add_page_to_inactive_list_tail().Quoted 7 lines
Quoted 5 lines
Is that
a worthwhile addition to this (ever growing) project? That would definitely have an impact on the other code if not all done withinswap_prefetch.c.. which would also be quite a large open coded something.Do both of the above in a new function in
swap.c.That'll require the caller to do lru locking.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
I'd add an
lru_cache_add_tail, use it instead of the currentlru_cache_addthat Con's got now, and just implement it in a simple manner, without pagevecs.umm, that's what I said ;)
You said
del_page_from_lru(), which doesn't belong in a function calledlru_cache_add_tail.
Just so it's clear I understand, is this what you (both) had in mind? Inline so it's not built for !CONFIG_SWAP_PREFETCH
Cheers,
Con
---
include/linux/mm_inline.h +7 -0
@@ -14,6 +14,13 @@ add_page_to_inactive_list(struct zone *z }static inline void +add_page_to_inactive_list_tail (struct zone *zone,struct page *page) +{ +list_add_tail (&page->lru, &zone->inactive_list); + zone->nr_inactive++; +} + +static inline void del_page_from_active_list (struct zone *zone,struct page *page) {list_del (&page->lru);
include/linux/swap.h +3 -0
@@ -216,6 +216,9 @@ extern int shmem_unuse(swp_entry_t entryextern void swap_unplug_io_fn (struct backing_dev_info *,struct page *);#ifdef CONFIG_SWAP_PREFETCH +/* mm/swap.c */ +extern void lru_cache_add_tail (struct page *page); +/* mm/swap_prefetch.c */ extern int swap_prefetch; struct swapped_entry {
mm/swap.c +7 -0
@@ -156,6 +156,13 @@ void fastcall lru_cache_add_active(strucput_cpu_var (lru_add_active_pvecs); } +inline void lru_cache_add_tail (struct page *page) +{ +struct zone *zone =page_zone (page); + +add_page_to_inactive_list_tail (zone, page); +} +static void __lru_add_drain (int cpu) {struct pagevec *pvec = &per_cpu (lru_add_pvecs, cpu);
mm/swap_prefetch.c +1 -1
@@ -196,7 +196,7 @@ static enum trickle_return trickle_swap_ goto out_release; } -lru_cache_add (page); +lru_cache_add_tail (page);if (unlikely (swap_readpage (NULL , page))) { ret =TRICKLE_DELAY ; goto out_release;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 3 lines · Con Kolivas
Just so it's clear I understand, is this what you (both) had in mind? Inline so it's not built for !CONFIG_SWAP_PREFETCH
Close...
mm/swap.c void fastcall lru_cache_add_active(struc · line 159
Quoted 9 lines
Index:
linux-2.6.16-rc2-ck1/mm/swap.c
===================================================================mm/swap.c +1
-0@@ -156,6 +156,13 @@ void fastcall lru_cache_add_active(strucput_cpu_var (lru_add_active_pvecs); } +inline void lru_cache_add_tail (struct page *page)
Is this inline going to do what you intend?
mm/swap.c void fastcall lru_cache_add_active(struc · line 162
Quoted 3 lines
mm/swap.c +3
-0+{ +struct zone *zone =page_zone (page); +
spin_lock_irq(&zone->lru_lock);
mm/swap.c void fastcall lru_cache_add_active(struc · line 163
Quoted 1 line
mm/swap.c +1
-0+add_page_to_inactive_list_tail (zone, page);
spin_unlock_irq(&zone->lru_lock);
Quoted 5 lines
mm/swap.c +2
-0+} +static void __lru_add_drain (int cpu) {struct pagevec *pvec = &per_cpu (lru_add_pvecs, cpu);
Signature · 8 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 9 lines · Nick Piggin
Quoted 2 lines · Con Kolivas
Just so it's clear I understand, is this what you (both) had in mind? Inline so it's not built for !CONFIG_SWAP_PREFETCH
Close...
Quoted 1 line
+inline void
lru_cache_add_tail(struct page *page)Is this inline going to do what you intend?
I don't care if it's actually inlined, but the subtleties of compilers is way beyond me. All it positively achieves is silencing the unused function warning so I had hoped it meant that function was not built. I tend to be wrong though...
Quoted 5 lines
spin_lock_irq(&zone->lru_lock);mm/swap.c void fastcall lru_cache_add_active(struc · line 163
Quoted 1 line
mm/swap.c +1
-0+add_page_to_inactive_list_tail (zone, page);spin_unlock_irq(&zone->lru_lock);
Thanks!
Cheers,
Con
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 10 lines · Con Kolivas
Quoted 6 lines · Nick Piggin
Quoted 2 lines · Con Kolivas
Just so it's clear I understand, is this what you (both) had in mind? Inline so it's not built for !CONFIG_SWAP_PREFETCH
Close...
Quoted 7 lines
Quoted 3 lines
Quoted 1 line
+inline void
lru_cache_add_tail(struct page *page)Is this inline going to do what you intend?
I don't care if it's actually inlined, but the subtleties of compilers is way beyond me. All it positively achieves is silencing the unused function warning so I had hoped it meant that function was not built. I tend to be wrong though...
I don't think it can because it is not used in the same file. You'd have to put it into the header file.
Not sure why it silences the unused function warning. You didn't replace a 'static' with the inline? I don't think there is any other way the compiler can know the function isn't used externally.
Signature · 8 lines
SUSE Labs, Novell Inc. Send instant messages to your online friends http://au.messenger.yahoo.com -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Quoted 12 lines · Nick Piggin
Quoted 11 lines · Con Kolivas
Quoted 9 lines · Nick Piggin
Quoted 2 lines · Con Kolivas
Just so it's clear I understand, is this what you (both) had in mind? Inline so it's not built for !CONFIG_SWAP_PREFETCH
Close...
Quoted 1 line
+inline void
lru_cache_add_tail(struct page *page)Is this inline going to do what you intend?
Quoted 7 lines
Quoted 4 lines
I don't care if it's actually inlined, but the subtleties of compilers is way beyond me. All it positively achieves is silencing the unused function warning so I had hoped it meant that function was not built. I tend to be wrong though...
I don't think it can because it is not used in the same file. You'd have to put it into the header file.
Yes that was the stream of "unimplemented" errors we started seeing on new gccs that couldn't inline and said so. The build process is mystical and somewhat random in order but I guessed if it encounters this first it should be able to inline it. However as I said I don't really need it inlined.
Quoted 1 line
Not sure why it silences the unused function warning.
It probably just fools it... Will probably warn on newer gccs soon.
Quoted 3 lines
You didn't
replace a 'static' with the inline? I don't think there is any other way the compiler can know the function isn't used externally.
Well I could always just put it in a header file under CONFIG_SWAP_PREFETCH.. I was trying to do the swap.c thing that akpm suggested though.
Cheers,
Con
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>