Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185142
b: refs/heads/master
c: fb90ef9
h: refs/heads/master
v: v3
  • Loading branch information
Yinghai Lu authored and Ingo Molnar committed Feb 26, 2010
1 parent 3ff4ed2 commit 1dab01d
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2ee78f7b1d8ada2615ecbcd9fea70580008bd6ce
refs/heads/master: fb90ef93df654f2678933efbbf864adac0ae490e
6 changes: 6 additions & 0 deletions trunk/arch/x86/kernel/setup_percpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ static void * __init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)

static void __init pcpu_fc_free(void *ptr, size_t size)
{
#ifdef CONFIG_NO_BOOTMEM
u64 start = __pa(ptr);
u64 end = start + size;
free_early_partial(start, end);
#else
free_bootmem(__pa(ptr), size);
#endif
}

static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/early_res.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
extern void reserve_early(u64 start, u64 end, char *name);
extern void reserve_early_overlap_ok(u64 start, u64 end, char *name);
extern void free_early(u64 start, u64 end);
void free_early_partial(u64 start, u64 end);
extern void early_res_to_bootmem(u64 start, u64 end);

void reserve_early_without_check(u64 start, u64 end, char *name);
Expand Down
55 changes: 55 additions & 0 deletions trunk/kernel/early_res.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,40 @@ static void __init drop_range(int i)
early_res_count--;
}

static void __init drop_range_partial(int i, u64 start, u64 end)
{
u64 common_start, common_end;
u64 old_start, old_end;

old_start = early_res[i].start;
old_end = early_res[i].end;
common_start = max(old_start, start);
common_end = min(old_end, end);

/* no overlap ? */
if (common_start >= common_end)
return;

if (old_start < common_start) {
/* make head segment */
early_res[i].end = common_start;
if (old_end > common_end) {
/* add another for left over on tail */
reserve_early_without_check(common_end, old_end,
early_res[i].name);
}
return;
} else {
if (old_end > common_end) {
/* reuse the entry for tail left */
early_res[i].start = common_end;
return;
}
/* all covered */
drop_range(i);
}
}

/*
* Split any existing ranges that:
* 1) are marked 'overlap_ok', and
Expand Down Expand Up @@ -284,6 +318,27 @@ void __init free_early(u64 start, u64 end)
drop_range(i);
}

void __init free_early_partial(u64 start, u64 end)
{
struct early_res *r;
int i;

try_next:
i = find_overlapped_early(start, end);
if (i >= max_early_res)
return;

r = &early_res[i];
/* hole ? */
if (r->end >= end && r->start <= start) {
drop_range_partial(i, start, end);
return;
}

drop_range_partial(i, start, end);
goto try_next;
}

#ifdef CONFIG_NO_BOOTMEM
static void __init subtract_early_res(struct range *range, int az)
{
Expand Down
3 changes: 0 additions & 3 deletions trunk/mm/percpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1929,10 +1929,7 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, ssize_t dyn_size,
}
/* copy and return the unused part */
memcpy(ptr, __per_cpu_load, ai->static_size);
#ifndef CONFIG_NO_BOOTMEM
/* fix partial free ! */
free_fn(ptr + size_sum, ai->unit_size - size_sum);
#endif
}
}

Expand Down

0 comments on commit 1dab01d

Please sign in to comment.