OSDN Git Service

ipc: prevent lockup on alloc_msg and free_msg
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / ipc / mqueue.c
index 5e24eb0..6ed7482 100644 (file)
@@ -373,7 +373,8 @@ static void mqueue_evict_inode(struct inode *inode)
        struct user_struct *user;
        unsigned long mq_bytes, mq_treesize;
        struct ipc_namespace *ipc_ns;
-       struct msg_msg *msg;
+       struct msg_msg *msg, *nmsg;
+       LIST_HEAD(tmp_msg);
 
        clear_inode(inode);
 
@@ -384,10 +385,15 @@ static void mqueue_evict_inode(struct inode *inode)
        info = MQUEUE_I(inode);
        spin_lock(&info->lock);
        while ((msg = msg_get(info)) != NULL)
-               free_msg(msg);
+               list_add_tail(&msg->m_list, &tmp_msg);
        kfree(info->node_cache);
        spin_unlock(&info->lock);
 
+       list_for_each_entry_safe(msg, nmsg, &tmp_msg, m_list) {
+               list_del(&msg->m_list);
+               free_msg(msg);
+       }
+
        /* Total amount of bytes accounted for the mqueue */
        mq_treesize = info->attr.mq_maxmsg * sizeof(struct msg_msg) +
                min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) *