Пример #1
0
static int check_slab(struct kmem_cache *s, struct page *page)
{
	int maxobj;

	VM_BUG_ON(!irqs_disabled());

	if (!PageSlab(page)) {
		slab_err(s, page, "Not a valid slab page");
		return 0;
	}

	maxobj = order_objects(compound_order(page), s->size, s->reserved);
	if (page->objects > maxobj) {
		slab_err(s, page, "objects %u > max %u",
			s->name, page->objects, maxobj);
		return 0;
	}
	if (page->inuse > page->objects) {
		slab_err(s, page, "inuse %u > max %u",
			s->name, page->inuse, page->objects);
		return 0;
	}
	/* Slab_pad_check fixes things up after itself */
	slab_pad_check(s, page);
	return 1;
}
Пример #2
0
/* 给定最小objects数目要求和最大order计算较合适的order */
static int slab_order(int size, int min_objects,
				int max_order, int fract_leftover)
{
	int order;
	int rem;
	int min_order = slub_min_order;
    /* 当前最小order下对象太多了 */
	if (order_objects(min_order, size) > MAX_OBJS_PER_PAGE)
		return get_order(size * MAX_OBJS_PER_PAGE) - 1;


	for (order = max(min_order,
                  /* 找到最低对齐位对应的order,然后和最小order选个最大的 */
				fls(min_objects * size - 1) - PAGE_SHIFT);
			order <= max_order; order++) {

		unsigned long slab_size = PAGE_SIZE << order;

        /* slab太小了 */
		if (slab_size < min_objects * size)
			continue;
        /*  计算剩余字节数   */
		rem = (slab_size) % size;
        /* 剩余字节数满足要求,也就是最大不浪费总共大小的四分之一 */
		if (rem <= slab_size / fract_leftover)
			break;

	}

	return order;
}
Пример #3
0
static inline struct kmem_cache_order_objects oo_make(int order,
		unsigned long size, int reserved)
{
	struct kmem_cache_order_objects x = {
		(order << OO_SHIFT) + order_objects(order, size, reserved)
	};

	return x;
}
Пример #4
0
/*
 * Determine if a certain object on a page is on the freelist. Must hold the
 * slab lock to guarantee that the chains are in a consistent state.
 */
static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
{
	int nr = 0;
	void *fp;
	void *object = NULL;
	unsigned long max_objects;

	fp = page->freelist;
	while (fp && nr <= page->objects) {
		if (fp == search)
			return 1;
		if (!check_valid_pointer(s, page, fp)) {
			if (object) {
				object_err(s, page, object,
					"Freechain corrupt");
				set_freepointer(s, object, NULL);
				break;
			} else {
				slab_err(s, page, "Freepointer corrupt");
				page->freelist = NULL;
				page->inuse = page->objects;
				slab_fix(s, "Freelist cleared");
				return 0;
			}
			break;
		}
		object = fp;
		fp = get_freepointer(s, object);
		nr++;
	}

	max_objects = order_objects(compound_order(page), s->size, s->reserved);
	if (max_objects > MAX_OBJS_PER_PAGE)
		max_objects = MAX_OBJS_PER_PAGE;

	if (page->objects != max_objects) {
		slab_err(s, page, "Wrong number of objects. Found %d but "
			"should be %d", page->objects, max_objects);
		page->objects = max_objects;
		slab_fix(s, "Number of objects adjusted.");
	}
	if (page->inuse != page->objects - nr) {
		slab_err(s, page, "Wrong object count. Counter is %d but "
			"counted were %d", page->inuse, page->objects - nr);
		page->inuse = page->objects - nr;
		slab_fix(s, "Object count adjusted.");
	}
	return search == NULL;
}
Пример #5
0
static int calculate_order(int size)
{
	int order;
	int min_objects;
	int fraction;
	int max_objects;

    /* 计算最小允许的object数目和最大的object数目 */
	min_objects = slub_min_objects;
	if (!min_objects)
		min_objects = MIN_OBJECT;
	max_objects = order_objects(slub_max_order, size);
	min_objects = min(min_objects, max_objects);

    /* 还是不行,缩小最小对象的要求 */
	while (min_objects > 1) {
		fraction = 16;
		while (fraction >= 4) {
		    /* 给定size和最小object数目计算order */
			order = slab_order(size, min_objects,
					slub_max_order, fraction);
            /* 该size和objects数目计算出的order比较适合 */
			if (order <= slub_max_order)
				return order;
            /* 降低粒度,也就是允许更多的浪费 */
			fraction /= 2;
		}
		min_objects--;
	}

	/*
	 尝试将单个对象放入给定块中
	 */
	order = slab_order(size, 1, slub_max_order, 1);
	if (order <= slub_max_order)
		return order;

	/*
	尝试是否能放入最大的order
	 */
	order = slab_order(size, 1, MAX_ORDER, 1);
	if (order < MAX_ORDER)
		return order;
	return -1;
}