Example #1
0
File: lmb.c Project: 274914765/C
static u64 __init lmb_alloc_nid_region(struct lmb_property *mp,
                       u64 (*nid_range)(u64, u64, int *),
                       u64 size, u64 align, int nid)
{
    u64 start, end;

    start = mp->base;
    end = start + mp->size;

    start = lmb_align_up(start, align);
    while (start < end) {
        u64 this_end;
        int this_nid;

        this_end = nid_range(start, end, &this_nid);
        if (this_nid == nid) {
            u64 ret = lmb_alloc_nid_unreserved(start, this_end,
                               size, align);
            if (ret != ~(u64)0)
                return ret;
        }
        start = this_end;
    }

    return ~(u64)0;
}
Example #2
0
File: lmb.c Project: 274914765/C
u64 __init __lmb_alloc_base(u64 size, u64 align, u64 max_addr)
{
    long i, j;
    u64 base = 0;
    u64 res_base;

    BUG_ON(0 == size);

    size = lmb_align_up(size, align);

    /* On some platforms, make sure we allocate lowmem */
    /* Note that LMB_REAL_LIMIT may be LMB_ALLOC_ANYWHERE */
    if (max_addr == LMB_ALLOC_ANYWHERE)
        max_addr = LMB_REAL_LIMIT;

    for (i = lmb.memory.cnt - 1; i >= 0; i--) {
        u64 lmbbase = lmb.memory.region[i].base;
        u64 lmbsize = lmb.memory.region[i].size;

        if (lmbsize < size)
            continue;
        if (max_addr == LMB_ALLOC_ANYWHERE)
            base = lmb_align_down(lmbbase + lmbsize - size, align);
        else if (lmbbase < max_addr) {
            base = min(lmbbase + lmbsize, max_addr);
            base = lmb_align_down(base - size, align);
        } else
            continue;

        while (base && lmbbase <= base) {
            j = lmb_overlaps_region(&lmb.reserved, base, size);
            if (j < 0) {
                /* this area isn't reserved, take it */
                if (lmb_add_region(&lmb.reserved, base, size) < 0)
                    return 0;
                return base;
            }
            res_base = lmb.reserved.region[j].base;
            if (res_base < size)
                break;
            base = lmb_align_down(res_base - size, align);
        }
    }
    return 0;
}
Example #3
0
File: lmb.c Project: 274914765/C
u64 __init lmb_alloc_nid(u64 size, u64 align, int nid,
             u64 (*nid_range)(u64 start, u64 end, int *nid))
{
    struct lmb_region *mem = &lmb.memory;
    int i;

    BUG_ON(0 == size);

    size = lmb_align_up(size, align);

    for (i = 0; i < mem->cnt; i++) {
        u64 ret = lmb_alloc_nid_region(&mem->region[i],
                           nid_range,
                           size, align, nid);
        if (ret != ~(u64)0)
            return ret;
    }

    return lmb_alloc(size, align);
}
Example #4
0
phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr)
{
	long i, j;
	phys_addr_t base = 0;
	phys_addr_t res_base;

	for (i = lmb->memory.cnt-1; i >= 0; i--) {
		phys_addr_t lmbbase = lmb->memory.region[i].base;
		phys_size_t lmbsize = lmb->memory.region[i].size;

		if (lmbsize < size)
			continue;
		if (max_addr == LMB_ALLOC_ANYWHERE)
			base = lmb_align_down(lmbbase + lmbsize - size, align);
		else if (lmbbase < max_addr) {
			base = lmbbase + lmbsize;
			if (base < lmbbase)
				base = -1;
			base = min(base, max_addr);
			base = lmb_align_down(base - size, align);
		} else
			continue;

		while (base && lmbbase <= base) {
			j = lmb_overlaps_region(&lmb->reserved, base, size);
			if (j < 0) {
				/* This area isn't reserved, take it */
				if (lmb_add_region(&lmb->reserved, base,
							lmb_align_up(size,
								align)) < 0)
					return 0;
				return base;
			}
			res_base = lmb->reserved.region[j].base;
			if (res_base < size)
				break;
			base = lmb_align_down(res_base - size, align);
		}
	}
	return 0;
}