summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kovalenko <d.kovalenko@samsung.com>2015-12-04 02:59:54 -0800
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>2015-12-04 02:59:54 -0800
commitcfc1a85e181e7d25116f73450f7e28df4a772a03 (patch)
tree189c437f0b9111cb18ea710a1c415f64ada5e716
parentb830d539bc27e256261b027acd7766b5cec41cd0 (diff)
parentce7a3de04d7b16bbbdb76efc57906a845d9e581d (diff)
downloadswap-modules-tizen_2.4_uihv.tar.gz
swap-modules-tizen_2.4_uihv.tar.bz2
swap-modules-tizen_2.4_uihv.zip
Merge "[FIX] deadlock in img_proc_del_ip()" into tizen_2.4_devtizen_2.4_uihv
-rw-r--r--us_manager/img/img_file.c19
-rw-r--r--us_manager/img/img_file.h6
-rw-r--r--us_manager/img/img_proc.c61
3 files changed, 53 insertions, 33 deletions
diff --git a/us_manager/img/img_file.c b/us_manager/img/img_file.c
index ec4903c4..978a78d9 100644
--- a/us_manager/img/img_file.c
+++ b/us_manager/img/img_file.c
@@ -37,7 +37,7 @@ static void img_del_ip_by_list(struct img_ip *ip);
* @param dentry Dentry of file
* @return Pointer to the created img_file struct
*/
-struct img_file *create_img_file(struct dentry *dentry)
+struct img_file *img_file_create(struct dentry *dentry)
{
struct img_file *file;
@@ -50,6 +50,7 @@ struct img_file *create_img_file(struct dentry *dentry)
file->dentry = dentry;
INIT_LIST_HEAD(&file->ip_list);
INIT_LIST_HEAD(&file->list);
+ atomic_set(&file->use, 1);
return file;
}
@@ -60,7 +61,7 @@ struct img_file *create_img_file(struct dentry *dentry)
* @param file remove object
* @return Void
*/
-void free_img_file(struct img_file *file)
+static void img_file_free(struct img_file *file)
{
struct img_ip *ip, *tmp;
@@ -82,6 +83,20 @@ static void img_del_ip_by_list(struct img_ip *ip)
list_del(&ip->list);
}
+void img_file_get(struct img_file *file)
+{
+ WARN_ON(!atomic_read(&file->use));
+ atomic_inc(&file->use);
+}
+
+void img_file_put(struct img_file *file)
+{
+ if (atomic_dec_and_test(&file->use))
+ img_file_free(file);
+
+ return;
+}
+
static struct img_ip *find_img_ip(struct img_file *file, unsigned long addr,
struct probe_desc *pd)
{
diff --git a/us_manager/img/img_file.h b/us_manager/img/img_file.h
index 7b33980a..82870e01 100644
--- a/us_manager/img/img_file.h
+++ b/us_manager/img/img_file.h
@@ -38,10 +38,12 @@ struct img_file {
struct list_head list; /**< For img_proc */
struct dentry *dentry; /**< Dentry of file */
struct list_head ip_list; /**< For img_ip */
+ atomic_t use;
};
-struct img_file *create_img_file(struct dentry *dentry);
-void free_img_file(struct img_file *ip);
+struct img_file *img_file_create(struct dentry *dentry);
+void img_file_get(struct img_file *file);
+void img_file_put(struct img_file *file);
int img_file_add_ip(struct img_file *file, unsigned long addr,
struct probe_desc *pd);
diff --git a/us_manager/img/img_proc.c b/us_manager/img/img_proc.c
index ef6805f8..e6999417 100644
--- a/us_manager/img/img_proc.c
+++ b/us_manager/img/img_proc.c
@@ -69,10 +69,12 @@ void free_img_proc(struct img_proc *proc)
{
struct img_file *file, *tmp;
+ write_lock(&proc->rwlock);
list_for_each_entry_safe(file, tmp, &proc->file_list, list) {
img_del_file_by_list(file);
- free_img_file(file);
+ img_file_put(file);
}
+ write_unlock(&proc->rwlock);
kfree(proc);
}
@@ -90,14 +92,16 @@ static void img_del_file_by_list(struct img_file *file)
}
/* called with read_[lock/unlock](&proc->rwlock) */
-static struct img_file *find_img_file(struct img_proc *proc,
- struct dentry *dentry)
+static struct img_file *img_file_find_get(struct img_proc *proc,
+ struct dentry *dentry)
{
struct img_file *file;
list_for_each_entry(file, &proc->file_list, list) {
- if (file->dentry == dentry)
+ if (file->dentry == dentry) {
+ img_file_get(file);
return file;
+ }
}
return NULL;
@@ -119,28 +123,25 @@ int img_proc_add_ip(struct img_proc *proc, struct dentry *dentry,
struct img_file *file;
write_lock(&proc->rwlock);
- file = find_img_file(proc, dentry);
- if (file) {
- ret = img_file_add_ip(file, addr, pd);
- goto unlock;
- }
+ file = img_file_find_get(proc, dentry);
+ write_unlock(&proc->rwlock);
+
+ if (!file) {
+ file = img_file_create(dentry);
+ if (!file)
+ return -ENOMEM;
- file = create_img_file(dentry);
- if (file == NULL) {
- ret = -ENOMEM;
- goto unlock;
+ img_file_get(file);
+ write_lock(&proc->rwlock);
+ img_add_file_by_list(proc, file);
+ write_unlock(&proc->rwlock);
}
ret = img_file_add_ip(file, addr, pd);
- if (ret) {
+ if (ret)
printk(KERN_INFO "Cannot add ip to img file\n");
- free_img_file(file);
- } else {
- img_add_file_by_list(proc, file);
- }
-unlock:
- write_unlock(&proc->rwlock);
+ img_file_put(file);
return ret;
}
@@ -161,21 +162,23 @@ int img_proc_del_ip(struct img_proc *proc,
struct img_file *file;
write_lock(&proc->rwlock);
- file = find_img_file(proc, dentry);
- if (file == NULL) {
- ret = -EINVAL;
- goto unlock;
- }
+ file = img_file_find_get(proc, dentry);
+ write_unlock(&proc->rwlock);
+
+ if (!file)
+ return -EINVAL;
ret = img_file_del_ip(file, addr, pd);
if (ret == 0 && img_file_empty(file)) {
+ write_lock(&proc->rwlock);
img_del_file_by_list(file);
- free_img_file(file);
+ write_unlock(&proc->rwlock);
+ img_file_put(file);
}
-unlock:
- write_unlock(&proc->rwlock);
- return ret;
+ img_file_put(file);
+
+ return 0;
}
void img_proc_copy_to_sspt(struct img_proc *i_proc, struct sspt_proc *proc)