Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc0239f4 authored by Raviteja Tamatam's avatar Raviteja Tamatam
Browse files

drm/msm/sde: fix race condition in client_event_list deregister



In msm_release, there is condition where client_event_list nodes
can be deleted from msm_ioctl_deregister_event, when spin unlock
is called inside client_event_list loop. This change prevents
spin_unlock inside client_event_list loop.

Change-Id: I6b7c4c6113a9fd4698029e91486b16742d5c8b5b
Signed-off-by: default avatarRaviteja Tamatam <travitej@codeaurora.org>
parent 9d4600a1
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -1434,9 +1434,10 @@ static int msm_release(struct inode *inode, struct file *filp)
	struct drm_minor *minor = file_priv->minor;
	struct drm_device *dev = minor->dev;
	struct msm_drm_private *priv = dev->dev_private;
	struct msm_drm_event *node, *temp;
	struct msm_drm_event *node, *temp, *tmp_node;
	u32 count;
	unsigned long flags;
	LIST_HEAD(tmp_head);

	spin_lock_irqsave(&dev->event_lock, flags);
	list_for_each_entry_safe(node, temp, &priv->client_event_list,
@@ -1444,14 +1445,25 @@ static int msm_release(struct inode *inode, struct file *filp)
		if (node->base.file_priv != file_priv)
			continue;
		list_del(&node->base.link);
		list_add_tail(&node->base.link, &tmp_head);
	}
	spin_unlock_irqrestore(&dev->event_lock, flags);
		count = msm_event_client_count(dev, &node->info, true);

	list_for_each_entry_safe(node, temp, &tmp_head,
			base.link) {
		list_del(&node->base.link);
		count = msm_event_client_count(dev, &node->info, false);

		list_for_each_entry(tmp_node, &tmp_head, base.link) {
			if (tmp_node->event.type == node->info.event &&
				tmp_node->info.object_id ==
					node->info.object_id)
				count++;
		}
		if (!count)
			msm_register_event(dev, &node->info, file_priv, false);
		kfree(node);
		spin_lock_irqsave(&dev->event_lock, flags);
	}
	spin_unlock_irqrestore(&dev->event_lock, flags);

	return drm_release(inode, filp);
}