*参照元 [#pa89e1c3]
#backlinks

*説明 [#rb64599a]
-パス: [[linux-2.6.33/mm/vmalloc.c]]

-FIXME: これは何?
--説明


**引数 [#k66244e4]
-unsigned long size
--
-unsigned long align
--
-unsigned long vstar
--
-unsigned long vend
--
-int node
--
-gfp_t gfp_mask
--
--[[linux-2.6.33/gfp_t]]


**返り値 [#x2834ea4]
-struct vmap_area *
--
--[[linux-2.6.33/vmap_area]]


**参考 [#y379bfea]


*実装 [#w52d8916]
 /*
  * Allocate a region of KVA of the specified size and alignment, within the
  * vstart and vend.
  */
 static struct vmap_area *alloc_vmap_area(unsigned long size,
 				unsigned long align,
 				unsigned long vstart, unsigned long vend,
 				int node, gfp_t gfp_mask)
 {
 	struct vmap_area *va;
 	struct rb_node *n;
 	unsigned long addr;
 	int purged = 0;
 
-
--[[linux-2.6.33/rb_node]]

 	BUG_ON(!size);
 	BUG_ON(size & ~PAGE_MASK);
 
-サイズが 0 だったり、ページサイズの境界に合っていない場合はバグ
--[[linux-2.6.33/BUG_ON()]]
-
--[[linux-2.6.33/PAGE_MASK]]

 	va = kmalloc_node(sizeof(struct vmap_area),
 			gfp_mask & GFP_RECLAIM_MASK, node);
-
--[[linux-2.6.33/kmalloc_node()]]
-
--[[linux-2.6.33/GFP_RECLAIM_MASK]]

 	if (unlikely(!va))
 		return ERR_PTR(-ENOMEM);
 
-
--[[linux-2.6.33/unlikely()]]
-
--[[linux-2.6.33/ERR_PTR()]]
-
--[[linux-2.6.33/ENOMEM]]

 retry:
 	addr = ALIGN(vstart, align);
 
-
--[[linux-2.6.33/ALIGN()]]

 	spin_lock(&vmap_area_lock);
-
--[[linux-2.6.33/spin_lock()]]
-
--[[linux-2.6.33/vmap_area_lock(global)]]

 	if (addr + size - 1 < addr)
 		goto overflow;
 
 	/* XXX: could have a last_hole cache */
 	n = vmap_area_root.rb_node;
-
--[[linux-2.6.33/vmap_area_root(global)]]

 	if (n) {
 		struct vmap_area *first = NULL;
 
 		do {
 			struct vmap_area *tmp;
 			tmp = rb_entry(n, struct vmap_area, rb_node);
-
--[[linux-2.6.33/rb_entry()]]

 			if (tmp->va_end >= addr) {
 				if (!first && tmp->va_start < addr + size)
 					first = tmp;
 				n = n->rb_left;
 			} else {
 				first = tmp;
 				n = n->rb_right;
 			}
 		} while (n);
 
 		if (!first)
 			goto found;
 
 		if (first->va_end < addr) {
 			n = rb_next(&first->rb_node);
 			if (n)
 				first = rb_entry(n, struct vmap_area, rb_node);
 			else
 				goto found;
-
--[[linux-2.6.33/rb_next()]]

 		}
 
 		while (addr + size > first->va_start && addr + size <= vend) {
 			addr = ALIGN(first->va_end + PAGE_SIZE, align);
 			if (addr + size - 1 < addr)
 				goto overflow;
 
 			n = rb_next(&first->rb_node);
 			if (n)
 				first = rb_entry(n, struct vmap_area, rb_node);
 			else
 				goto found;
 		}
 	}
 found:
 	if (addr + size > vend) {
 overflow:
 		spin_unlock(&vmap_area_lock);
-
--[[linux-2.6.33/spin_unlock()]]

 		if (!purged) {
 			purge_vmap_area_lazy();
 			purged = 1;
 			goto retry;
-
--[[linux-2.6.33/purge_vmap_area_lazy()]]

 		}
 		if (printk_ratelimit())
 			printk(KERN_WARNING
 				"vmap allocation for size %lu failed: "
 				"use vmalloc=<size> to increase size.\n", size);
-
--[[linux-2.6.33/printk_ratelimit()]]
-
--[[linux-2.6.33/printk()]]
-
--[[linux-2.6.33/KERN_WARNING]]

 		kfree(va);
 		return ERR_PTR(-EBUSY);
-
--[[linux-2.6.33/kfree()]]

 	}
 
 	BUG_ON(addr & (align-1));
 
 	va->va_start = addr;
 	va->va_end = addr + size;
 	va->flags = 0;
 	__insert_vmap_area(va);
 	spin_unlock(&vmap_area_lock);
 
-
--[[linux-2.6.33/__insert_vmap_area()]]

 	return va;
 }


*コメント [#se35ce5f]


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS