Commit c5e147cf authored by Rene Herman's avatar Rene Herman Committed by Ingo Molnar

x86: have set_memory_array_{uc,wb} coalesce memtypes.

Actually, might as well simply reconstruct the memtype list at free time
I guess. How is this for a coalescing version of the array functions?

Compiles, boots and provides me with:

  root@7ixe4:~# wc -l /debug/x86/pat_memtype_list
  53 /debug/x86/pat_memtype_list

otherwise (down from 16384+).
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 9a79f4f4
...@@ -942,21 +942,38 @@ EXPORT_SYMBOL(set_memory_uc); ...@@ -942,21 +942,38 @@ EXPORT_SYMBOL(set_memory_uc);
int set_memory_array_uc(unsigned long *addr, int addrinarray) int set_memory_array_uc(unsigned long *addr, int addrinarray)
{ {
unsigned long start;
unsigned long end;
int i; int i;
/* /*
* for now UC MINUS. see comments in ioremap_nocache() * for now UC MINUS. see comments in ioremap_nocache()
*/ */
for (i = 0; i < addrinarray; i++) { for (i = 0; i < addrinarray; i++) {
if (reserve_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE, start = __pa(addr[i]);
_PAGE_CACHE_UC_MINUS, NULL)) for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
if (end != __pa(addr[i + 1]))
break;
i++;
}
if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
goto out; goto out;
} }
return change_page_attr_set(addr, addrinarray, return change_page_attr_set(addr, addrinarray,
__pgprot(_PAGE_CACHE_UC_MINUS), 1); __pgprot(_PAGE_CACHE_UC_MINUS), 1);
out: out:
while (--i >= 0) for (i = 0; i < addrinarray; i++) {
free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE); unsigned long tmp = __pa(addr[i]);
if (tmp == start)
break;
for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
if (end != __pa(addr[i + 1]))
break;
i++;
}
free_memtype(tmp, end);
}
return -EINVAL; return -EINVAL;
} }
EXPORT_SYMBOL(set_memory_array_uc); EXPORT_SYMBOL(set_memory_array_uc);
...@@ -997,9 +1014,18 @@ EXPORT_SYMBOL(set_memory_wb); ...@@ -997,9 +1014,18 @@ EXPORT_SYMBOL(set_memory_wb);
int set_memory_array_wb(unsigned long *addr, int addrinarray) int set_memory_array_wb(unsigned long *addr, int addrinarray)
{ {
int i; int i;
for (i = 0; i < addrinarray; i++)
free_memtype(__pa(addr[i]), __pa(addr[i]) + PAGE_SIZE);
for (i = 0; i < addrinarray; i++) {
unsigned long start = __pa(addr[i]);
unsigned long end;
for (end = start + PAGE_SIZE; i < addrinarray - 1; end += PAGE_SIZE) {
if (end != __pa(addr[i + 1]))
break;
i++;
}
free_memtype(start, end);
}
return change_page_attr_clear(addr, addrinarray, return change_page_attr_clear(addr, addrinarray,
__pgprot(_PAGE_CACHE_MASK), 1); __pgprot(_PAGE_CACHE_MASK), 1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment