From: Robin Holt <holt@sgi.com>
To: linux-ia64@vger.kernel.org
Subject: Re: Uncached memory allocator for ia64.
Date: Sat, 25 Sep 2004 12:40:34 +0000 [thread overview]
Message-ID: <20040925124030.GA23068@attica.americas.sgi.com> (raw)
In-Reply-To: <20040914151629.GA21118@lnx-holt.americas.sgi.com>
On Thu, Sep 23, 2004 at 03:12:40PM -0700, Luck, Tony wrote:
>
> >I am not sure what will be acceptable at this point. Should I write
> >an uncached allocator which grabs the granules at boot time before they
> >are ever initialized for cacheable use? If so, would it be acceptable
> >to just shrink each efi memory map entry by a command line specified
> >size during the efi_memmap_walk callout? At this point I am so vague
> >on what I should be doing that I am afraid to do much of anything.
>
> We already make adjustments to the efi memory map (to trim sections to
> granule boundaries) ... but another hack on top of the layers of ugliness
> there already is going to make things worse. Perhaps someday we can
> delete it all and start over.
>
> Grabbing your memory out of the map before any of the rest of Linux
> ever sees it sounds to be a good idea ... it avoids wasting memory
> for page structures in mem_map that can only get you into trouble
> if anyone ever looks at them.
>
> If your allocator only needs a small number of pages from each node, then
> it is possible that you'd be able to feed it the trimmed off scraps
> from incomplete granules, rather than pull a whole granule. So you
> might want to run your scan through the efi map before anyone else
> messes with it.
>
I have a first pass at this. This has not even been compiled yet.
It is only a check to ensure I am on the right track.
Robin
-------- uncached_allocator --------
Index: linux-2.6/arch/ia64/mm/discontig.c
=================================--- linux-2.6.orig/arch/ia64/mm/discontig.c 2004-09-24 10:47:03.000000000 -0500
+++ linux-2.6/arch/ia64/mm/discontig.c 2004-09-25 07:11:17.000000000 -0500
@@ -544,6 +544,58 @@
printk("%d free buffer pages\n", nr_free_buffer_pages());
}
+struct node_uncached_regions {
+ long paddr;
+ int uncached_pages;
+ unsigned long bits[1]; /* Bitmap for managing pages. */
+};
+
+static struct node_uncached_regions *node_uncached_regions[MAX_COMPACT_NODES];
+
+/* Just for discussion */
+#define UNCACHED_GRANULES_PER_NODE 2
+
+/* I am assuming start is granule aligned. I need to verify that further. */
+void reserve_uncached_memory(unsigned long start, unsigned long len, void *arg, int nid)
+{
+ void (*func)(unsigned long, unsigned long, int);
+
+ func = arg;
+
+ if ((UNCACHED_GRANULES_PER_NODE = 0) ||
+ (UNCACHED_GRANULES_PER_NODE * IA64_GRANULE_SIZE >= len)) {
+ (*func)(start, len, nid);
+ return;
+ }
+
+ if (node_uncached_regions[nid] = NULL) {
+ unsigned long grs;
+ int bytes, uncached_pages;
+ struct node_uncached_regions *uncached_region;
+
+ uncached_pages = UNCACHED_GRANULES_PER_NODE * IA64_GRANULE_SIZE / PAGE_SIZE;
+ bytes = sizeof(struct node_uncached_regions) + uncached_pages/8;
+ uncached_region = alloc_bootmem_node(NODE_DATA(nid), bytes);
+ if (uncached_region = NULL) {
+ (*func)(start, len, nid);
+ return;
+ }
+ memset(uncached_region, 0, bytes);
+ uncached_region->paddr = start;
+ uncached_region->uncached_pages = uncached_pages;
+ node_uncached_regions[nid] = uncached_region;
+ }
+
+ if ((node_uncached_regions[nid] != NULL) &&
+ (node_uncached_regions[nid].paddr = start_address)) {
+ start += UNCACHED_GRANULES_PER_NODE * IA64_GRANULE_SIZE;
+ len -= UNCACHED_GRANULES_PER_NODE * IA64_GRANULE_SIZE;
+ }
+
+ (*func)(start, len, nid);
+}
+
+
/**
* call_pernode_memory - use SRAT to call callback functions with node info
* @start: physical start of range
@@ -560,7 +612,6 @@
void call_pernode_memory(unsigned long start, unsigned long len, void *arg)
{
unsigned long rs, re, end = start + len;
- void (*func)(unsigned long, unsigned long, int);
int i;
start = PAGE_ALIGN(start);
@@ -568,12 +619,10 @@
if (start >= end)
return;
- func = arg;
-
if (!num_node_memblks) {
/* No SRAT table, so assume one node (node 0) */
if (start < end)
- (*func)(start, end - start, 0);
+ reserve_uncached_memory(start, end-start, arg, 0);
return;
}
@@ -583,7 +632,7 @@
node_memblk[i].size);
if (rs < re)
- (*func)(rs, re - rs, node_memblk[i].nid);
+ reserve_uncached_memory(rs, re - rs, arg, node_memblk[i].nid);
if (re = end)
break;
next prev parent reply other threads:[~2004-09-25 12:40 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-14 15:16 Uncached memory allocator for ia64 Robin Holt
2004-09-15 8:23 ` David Mosberger
2004-09-15 11:04 ` Robin Holt
2004-09-15 11:14 ` David Mosberger
2004-09-17 14:34 ` Robin Holt
2004-09-23 21:09 ` Robin Holt
2004-09-23 22:12 ` Luck, Tony
2004-09-23 23:01 ` Robin Holt
2004-09-25 12:40 ` Robin Holt [this message]
2004-09-29 14:24 ` David Mosberger
2004-09-29 15:43 ` Robin Holt
2004-09-29 16:02 ` David Mosberger
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=20040925124030.GA23068@attica.americas.sgi.com \
--to=holt@sgi.com \
--cc=linux-ia64@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox