From: Dave Hansen <haveblue@us.ibm.com>
To: akpm@osdl.org
Cc: linux-kernel@vger.kernel.org, Dave Hansen <haveblue@us.ibm.com>
Subject: [PATCH 06/11] memory hotplug locking: zone span seqlock
Date: Fri, 02 Sep 2005 13:56:47 -0700 [thread overview]
Message-ID: <20050902205647.12ABF61D@kernel.beaverton.ibm.com> (raw)
In-Reply-To: <20050902205643.9A4EC17A@kernel.beaverton.ibm.com>
See the "fixup bad_range()" patch for more information, but this
actually creates a the lock to protect things making assumptions
about a zone's size staying constant at runtime.
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---
memhotplug-dave/include/linux/memory_hotplug.h | 39 +++++++++++++++++++++++--
memhotplug-dave/include/linux/mmzone.h | 15 +++++++++
memhotplug-dave/mm/page_alloc.c | 19 ++++++++----
3 files changed, 66 insertions(+), 7 deletions(-)
diff -puN include/linux/memory_hotplug.h~C6-zone-span_seqlock include/linux/memory_hotplug.h
--- memhotplug/include/linux/memory_hotplug.h~C6-zone-span_seqlock 2005-09-02 12:42:11.000000000 -0700
+++ memhotplug-dave/include/linux/memory_hotplug.h 2005-09-02 13:43:10.000000000 -0700
@@ -16,13 +16,36 @@ void pgdat_resize_lock(struct pglist_dat
static inline
void pgdat_resize_unlock(struct pglist_data *pgdat, unsigned long *flags)
{
- spin_lock_irqrestore(&pgdat->node_size_lock, *flags);
+ spin_unlock_irqrestore(&pgdat->node_size_lock, *flags);
}
static inline
void pgdat_resize_init(struct pglist_data *pgdat)
{
spin_lock_init(&pgdat->node_size_lock);
}
+/*
+ * Zone resizing functions
+ */
+static inline unsigned zone_span_seqbegin(struct zone *zone)
+{
+ return read_seqbegin(&zone->span_seqlock);
+}
+static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
+{
+ return read_seqretry(&zone->span_seqlock, iv);
+}
+static inline void zone_span_writelock(struct zone *zone)
+{
+ write_seqlock(&zone->span_seqlock);
+}
+static inline void zone_span_writeunlock(struct zone *zone)
+{
+ write_sequnlock(&zone->span_seqlock);
+}
+static inline void zone_seqlock_init(struct zone *zone)
+{
+ seqlock_init(&zone->span_seqlock);
+}
#else /* ! CONFIG_MEMORY_HOTPLUG */
/*
* Stub functions for when hotplug is off
@@ -30,5 +53,17 @@ void pgdat_resize_init(struct pglist_dat
static inline void pgdat_resize_lock(struct pglist_data *p, unsigned long *f) {}
static inline void pgdat_resize_unlock(struct pglist_data *p, unsigned long *f) {}
static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
-#endif
+
+static inline unsigned zone_span_seqbegin(struct zone *zone)
+{
+ return 0;
+}
+static inline int zone_span_seqretry(struct zone *zone, unsigned iv)
+{
+ return 0;
+}
+static inline void zone_span_writelock(struct zone *zone) {}
+static inline void zone_span_writeunlock(struct zone *zone) {}
+static inline void zone_seqlock_init(struct zone *zone) {}
+#endif /* ! CONFIG_MEMORY_HOTPLUG */
#endif /* __LINUX_MEMORY_HOTPLUG_H */
diff -puN include/linux/mmzone.h~C6-zone-span_seqlock include/linux/mmzone.h
--- memhotplug/include/linux/mmzone.h~C6-zone-span_seqlock 2005-09-02 12:42:11.000000000 -0700
+++ memhotplug-dave/include/linux/mmzone.h 2005-09-02 12:42:11.000000000 -0700
@@ -12,6 +12,7 @@
#include <linux/threads.h>
#include <linux/numa.h>
#include <linux/init.h>
+#include <linux/seqlock.h>
#include <asm/atomic.h>
/* Free memory management - zoned buddy allocator. */
@@ -137,6 +138,10 @@ struct zone {
* free areas of different sizes
*/
spinlock_t lock;
+#ifdef CONFIG_MEMORY_HOTPLUG
+ /* see spanned/present_pages for more description */
+ seqlock_t span_seqlock;
+#endif
struct free_area free_area[MAX_ORDER];
@@ -220,6 +225,16 @@ struct zone {
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
+ /*
+ * zone_start_pfn, spanned_pages and present_pages are all
+ * protected by span_seqlock. It is a seqlock because it has
+ * to be read outside of zone->lock, and it is done in the main
+ * allocator path. But, it is written quite infrequently.
+ *
+ * The lock is declared along with zone->lock because it is
+ * frequently read in proximity to zone->lock. It's good to
+ * give them a chance of being in the same cacheline.
+ */
unsigned long spanned_pages; /* total size, including holes */
unsigned long present_pages; /* amount of memory (excluding holes) */
diff -puN mm/page_alloc.c~C6-zone-span_seqlock mm/page_alloc.c
--- memhotplug/mm/page_alloc.c~C6-zone-span_seqlock 2005-09-02 12:42:11.000000000 -0700
+++ memhotplug-dave/mm/page_alloc.c 2005-09-02 13:43:10.000000000 -0700
@@ -32,6 +32,7 @@
#include <linux/sysctl.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
+#include <linux/memory_hotplug.h>
#include <linux/nodemask.h>
#include <linux/vmalloc.h>
@@ -79,12 +80,19 @@ unsigned long __initdata nr_all_pages;
static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
{
- if (page_to_pfn(page) >= zone->zone_start_pfn + zone->spanned_pages)
- return 1;
- if (page_to_pfn(page) < zone->zone_start_pfn)
- return 1;
+ int ret = 0;
+ unsigned seq;
+ unsigned long pfn = page_to_pfn(page);
- return 0;
+ do {
+ seq = zone_span_seqbegin(zone);
+ if (pfn >= zone->zone_start_pfn + zone->spanned_pages)
+ ret = 1;
+ else if (pfn < zone->zone_start_pfn)
+ ret = 1;
+ } while (zone_span_seqretry(zone, seq));
+
+ return ret;
}
static int page_is_consistent(struct zone *zone, struct page *page)
@@ -1970,6 +1978,7 @@ static void __init free_area_init_core(s
zone->name = zone_names[j];
spin_lock_init(&zone->lock);
spin_lock_init(&zone->lru_lock);
+ zone_seqlock_init(zone);
zone->zone_pgdat = pgdat;
zone->free_pages = 0;
_
next prev parent reply other threads:[~2005-09-02 20:59 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-09-02 20:56 [PATCH 01/11] memory hotplug prep: kill local_mapnr Dave Hansen
2005-09-02 20:56 ` [PATCH 02/11] memory hotplug prep: break out zone initialization Dave Hansen
2005-09-02 20:56 ` [PATCH 03/11] memory hotplug prep: __section_nr helper Dave Hansen
2005-09-03 14:59 ` Denis Vlasenko
2005-09-02 20:56 ` [PATCH 04/11] memory hotplug prep: fixup bad_range() Dave Hansen
2005-09-02 20:56 ` Dave Hansen [this message]
2005-09-02 20:56 ` [PATCH 05/11] memory hotplug locking: node_size_lock Dave Hansen
2005-09-02 20:56 ` [PATCH 07/11] memory hotplug: sysfs and add/remove functions Dave Hansen
2005-09-02 22:13 ` Andrew Morton
2005-09-02 22:18 ` Dave Hansen
2005-09-02 20:56 ` [PATCH 08/11] memory hotplug: move section_mem_map alloc to sparse.c Dave Hansen
2005-09-02 20:56 ` [PATCH 09/11] memory hotplug: call setup_per_zone_pages_min after hotplug Dave Hansen
2005-09-02 20:56 ` [PATCH 10/11] memory hotplug: i386 addition functions Dave Hansen
2005-09-02 20:56 ` [PATCH 11/11] memory hotplug: ppc64 specific hot-add functions Dave Hansen
2005-09-07 9:37 ` [PATCH 01/11] memory hotplug prep: kill local_mapnr Andrew Morton
2005-09-07 17:03 ` Dave Hansen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050902205647.12ABF61D@kernel.beaverton.ibm.com \
--to=haveblue@us.ibm.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.