⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slob.c

📁 最新最稳定的Linux内存管理模块源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		 */		if (node != -1 && page_to_nid(&sp->page) != node)			continue;#endif		/* Enough room on this page? */		if (sp->units < SLOB_UNITS(size))			continue;		/* Attempt to alloc */		prev = sp->list.prev;		b = slob_page_alloc(sp, size, align);		if (!b)			continue;		/* Improve fragment distribution and reduce our average		 * search time by starting our next search here. (see		 * Knuth vol 1, sec 2.5, pg 449) */		if (prev != slob_list->prev &&				slob_list->next != prev->next)			list_move_tail(slob_list, prev->next);		break;	}	spin_unlock_irqrestore(&slob_lock, flags);	/* Not enough space: must allocate a new page */	if (!b) {		b = slob_new_page(gfp & ~__GFP_ZERO, 0, node);		if (!b)			return 0;		sp = (struct slob_page *)virt_to_page(b);		set_slob_page(sp);		spin_lock_irqsave(&slob_lock, flags);		sp->units = SLOB_UNITS(PAGE_SIZE);		sp->free = b;		INIT_LIST_HEAD(&sp->list);		set_slob(b, SLOB_UNITS(PAGE_SIZE), b + SLOB_UNITS(PAGE_SIZE));		set_slob_page_free(sp, slob_list);		b = slob_page_alloc(sp, size, align);		BUG_ON(!b);		spin_unlock_irqrestore(&slob_lock, flags);	}	if (unlikely((gfp & __GFP_ZERO) && b))		memset(b, 0, size);	return b;}/* * slob_free: entry point into the slob allocator. */static void slob_free(void *block, int size){	struct slob_page *sp;	slob_t *prev, *next, *b = (slob_t *)block;	slobidx_t units;	unsigned long flags;	if (unlikely(ZERO_OR_NULL_PTR(block)))		return;	BUG_ON(!size);	sp = (struct slob_page *)virt_to_page(block);	units = SLOB_UNITS(size);	spin_lock_irqsave(&slob_lock, flags);	if (sp->units + units == SLOB_UNITS(PAGE_SIZE)) {		/* Go directly to page allocator. Do not pass slob allocator */		if (slob_page_free(sp))			clear_slob_page_free(sp);		clear_slob_page(sp);		free_slob_page(sp);		free_page((unsigned long)b);		goto out;	}	if (!slob_page_free(sp)) {		/* This slob page is about to become partially free. Easy! */		sp->units = units;		sp->free = b;		set_slob(b, units,			(void *)((unsigned long)(b +					SLOB_UNITS(PAGE_SIZE)) & PAGE_MASK));		set_slob_page_free(sp, &free_slob_small);		goto out;	}	/*	 * Otherwise the page is already partially free, so find reinsertion	 * point.	 */	sp->units += units;	if (b < sp->free) {		if (b + units == sp->free) {			units += slob_units(sp->free);			sp->free = slob_next(sp->free);		}		set_slob(b, units, sp->free);		sp->free = b;	} else {		prev = sp->free;		next = slob_next(prev);		while (b > next) {			prev = next;			next = slob_next(prev);		}		if (!slob_last(prev) && b + units == next) {			units += slob_units(next);			set_slob(b, units, slob_next(next));		} else			set_slob(b, units, next);		if (prev + slob_units(prev) == b) {			units = slob_units(b) + slob_units(prev);			set_slob(prev, units, slob_next(b));		} else			set_slob(prev, slob_units(prev), b);	}out:	spin_unlock_irqrestore(&slob_lock, flags);}/* * End of slob allocator proper. Begin kmem_cache_alloc and kmalloc frontend. */#ifndef ARCH_KMALLOC_MINALIGN#define ARCH_KMALLOC_MINALIGN __alignof__(unsigned long)#endif#ifndef ARCH_SLAB_MINALIGN#define ARCH_SLAB_MINALIGN __alignof__(unsigned long)#endifvoid *__kmalloc_node(size_t size, gfp_t gfp, int node){	unsigned int *m;	int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);	if (size < PAGE_SIZE - align) {		if (!size)			return ZERO_SIZE_PTR;		m = slob_alloc(size + align, gfp, align, node);		if (!m)			return NULL;		*m = size;		return (void *)m + align;	} else {		void *ret;		ret = slob_new_page(gfp | __GFP_COMP, get_order(size), node);		if (ret) {			struct page *page;			page = virt_to_page(ret);			page->private = size;		}		return ret;	}}EXPORT_SYMBOL(__kmalloc_node);void kfree(const void *block){	struct slob_page *sp;	if (unlikely(ZERO_OR_NULL_PTR(block)))		return;	sp = (struct slob_page *)virt_to_page(block);	if (slob_page(sp)) {		int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);		unsigned int *m = (unsigned int *)(block - align);		slob_free(m, *m + align);	} else		put_page(&sp->page);}EXPORT_SYMBOL(kfree);/* can't use ksize for kmem_cache_alloc memory, only kmalloc */size_t ksize(const void *block){	struct slob_page *sp;	BUG_ON(!block);	if (unlikely(block == ZERO_SIZE_PTR))		return 0;	sp = (struct slob_page *)virt_to_page(block);	if (slob_page(sp)) {		int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);		unsigned int *m = (unsigned int *)(block - align);		return SLOB_UNITS(*m) * SLOB_UNIT;	} else		return sp->page.private;}EXPORT_SYMBOL(ksize);struct kmem_cache {	unsigned int size, align;	unsigned long flags;	const char *name;	void (*ctor)(void *);};struct kmem_cache *kmem_cache_create(const char *name, size_t size,	size_t align, unsigned long flags, void (*ctor)(void *)){	struct kmem_cache *c;	c = slob_alloc(sizeof(struct kmem_cache),		GFP_KERNEL, ARCH_KMALLOC_MINALIGN, -1);	if (c) {		c->name = name;		c->size = size;		if (flags & SLAB_DESTROY_BY_RCU) {			/* leave room for rcu footer at the end of object */			c->size += sizeof(struct slob_rcu);		}		c->flags = flags;		c->ctor = ctor;		/* ignore alignment unless it's forced */		c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0;		if (c->align < ARCH_SLAB_MINALIGN)			c->align = ARCH_SLAB_MINALIGN;		if (c->align < align)			c->align = align;	} else if (flags & SLAB_PANIC)		panic("Cannot create slab cache %s\n", name);	return c;}EXPORT_SYMBOL(kmem_cache_create);void kmem_cache_destroy(struct kmem_cache *c){	slob_free(c, sizeof(struct kmem_cache));}EXPORT_SYMBOL(kmem_cache_destroy);void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node){	void *b;	if (c->size < PAGE_SIZE)		b = slob_alloc(c->size, flags, c->align, node);	else		b = slob_new_page(flags, get_order(c->size), node);	if (c->ctor)		c->ctor(b);	return b;}EXPORT_SYMBOL(kmem_cache_alloc_node);static void __kmem_cache_free(void *b, int size){	if (size < PAGE_SIZE)		slob_free(b, size);	else		free_pages((unsigned long)b, get_order(size));}static void kmem_rcu_free(struct rcu_head *head){	struct slob_rcu *slob_rcu = (struct slob_rcu *)head;	void *b = (void *)slob_rcu - (slob_rcu->size - sizeof(struct slob_rcu));	__kmem_cache_free(b, slob_rcu->size);}void kmem_cache_free(struct kmem_cache *c, void *b){	if (unlikely(c->flags & SLAB_DESTROY_BY_RCU)) {		struct slob_rcu *slob_rcu;		slob_rcu = b + (c->size - sizeof(struct slob_rcu));		INIT_RCU_HEAD(&slob_rcu->head);		slob_rcu->size = c->size;		call_rcu(&slob_rcu->head, kmem_rcu_free);	} else {		__kmem_cache_free(b, c->size);	}}EXPORT_SYMBOL(kmem_cache_free);unsigned int kmem_cache_size(struct kmem_cache *c){	return c->size;}EXPORT_SYMBOL(kmem_cache_size);const char *kmem_cache_name(struct kmem_cache *c){	return c->name;}EXPORT_SYMBOL(kmem_cache_name);int kmem_cache_shrink(struct kmem_cache *d){	return 0;}EXPORT_SYMBOL(kmem_cache_shrink);int kmem_ptr_validate(struct kmem_cache *a, const void *b){	return 0;}static unsigned int slob_ready __read_mostly;int slab_is_available(void){	return slob_ready;}void __init kmem_cache_init(void){	slob_ready = 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -