}\r
\r
/*\r
- * split allocated block from free block\r
+ * split new allocated block from free block\r
* the bitmap_sem and region_list_sem must be hold together\r
* the pnode is a ouput region node\r
*/\r
-static int region_split(struct list_head *region_list, struct vpu_mem_region_node *node, int index, int pfn)\r
+static int region_new(struct list_head *region_list, int index, int pfn)\r
{\r
int pfn_free = VPU_MEM_PFN(index);\r
// check pfn is smaller then target index region\r
return -EINVAL;\r
}\r
\r
- if (NULL == node) {\r
+ {\r
struct list_head *last;\r
+ struct vpu_mem_region_node *node;\r
// check target index region first\r
if (!VPU_MEM_IS_FREE(index)) {\r
#if VPU_MEM_DEBUG\r
\r
region_set_avail(index, VPU_MEM_AVAIL(index) + 1);\r
region_set_ref_count(index, VPU_MEM_REFC(index) + 1);\r
+ node->region.index = index;\r
+ node->region.ref_count = 1;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+/*\r
+ * link allocated block from free block\r
+ * the bitmap_sem and region_list_sem must be hold together\r
+ * the pnode is a ouput region node\r
+ */\r
+static int region_link(struct list_head *region_list, int index)\r
+{\r
+ struct vpu_mem_region_node *node = NULL;\r
+ struct list_head *list, *tmp;\r
+ list_for_each_safe(list, tmp, region_list) {\r
+ struct vpu_mem_region_node *p = list_entry(list, struct vpu_mem_region_node, list);\r
+ if (index == NODE_REGION_INDEX(p)) {\r
+ node = p;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (NULL == node) {\r
+ struct list_head *last;\r
+ DLOG("link non-exists index %d\n", index);\r
+\r
+ // malloc vpu_mem_region_node\r
+ node = kmalloc(sizeof(struct vpu_mem_region_node), GFP_KERNEL);\r
+ if (NULL == node) {\r
+#if VPU_MEM_DEBUG\r
+ printk(KERN_INFO "No space to allocate struct vpu_mem_region_node!");\r
+#endif\r
+ return -ENOMEM;\r
+ }\r
+\r
+ // search the last node\r
+ DLOG("search the last node\n");\r
+ for (last = region_list; !list_is_last(last, region_list);)\r
+ last = last->next;\r
+\r
+ DLOG("list_add_tail\n");\r
+ list_add_tail(&node->list, last);\r
+\r
node->region.index = index;\r
node->region.ref_count = 1;\r
} else {\r
- region_set_ref_count(index, VPU_MEM_REFC(index) + 1);\r
+ DLOG("link existed index %d\n", index);\r
node->region.ref_count++;\r
}\r
+ region_set_ref_count(index, VPU_MEM_REFC(index) + 1);\r
\r
return 0;\r
}\r
}\r
}\r
#if VPU_MEM_DEBUG\r
- printk(KERN_INFO "vpu_mem: search curr %d\n!", curr);\r
+ //printk(KERN_INFO "vpu_mem: search curr %d\n!", curr);\r
#endif\r
curr = VPU_MEM_NEXT_INDEX(curr);\r
#if VPU_MEM_DEBUG\r
- printk(KERN_INFO "vpu_mem: search next %d\n!", curr);\r
+ //printk(KERN_INFO "vpu_mem: search next %d\n!", curr);\r
#endif\r
}\r
\r
\r
down_write(&data->sem);\r
{\r
- int ret = region_split(&data->region_list, NULL, best_fit, pfn);\r
+ int ret = region_new(&data->region_list, best_fit, pfn);\r
if (ret)\r
best_fit = -1;\r
}\r
\r
static int vpu_mem_link(struct file *file, int index)\r
{\r
+ int err;\r
struct vpu_mem_data *data = (struct vpu_mem_data *)file->private_data;\r
\r
if (!is_vpu_mem_file(file)) {\r
return -EINVAL;\r
}\r
\r
- /* caller should hold the write lock on vpu_mem_sem! */\r
- DLOG("link index %d\n", index);\r
+ // check target index region first\r
+ if (VPU_MEM_IS_FREE(index)) {\r
+#if VPU_MEM_DEBUG\r
+ printk(KERN_INFO "try to link free region %d!", index);\r
+#endif\r
+ return -1;\r
+ }\r
\r
+ /* caller should hold the write lock on vpu_mem_sem! */\r
down_write(&data->sem);\r
- { // search exists index\r
- struct list_head *list, *tmp;\r
- list_for_each_safe(list, tmp, &data->region_list) {\r
- struct vpu_mem_region_node *node = list_entry(list, struct vpu_mem_region_node, list);\r
- if (index == NODE_REGION_INDEX(node)) {\r
- region_split(&data->region_list, node, index, VPU_MEM_PFN(index));\r
- up_write(&data->sem);\r
- return 0;\r
- }\r
- }\r
- // non-exists index\r
- region_split(&data->region_list, NULL, index, VPU_MEM_PFN(index));\r
- }\r
+ err = region_link(&data->region_list, index);\r
up_write(&data->sem);\r
+ DLOG("link index %d ret %d\n", index, err);\r
\r
- return 0;\r
+ return err;\r
}\r
\r
void vpu_mem_flush(struct file *file, long index)\r