vhost: fix ref cnt checking deadlock
authorMichael S. Tsirkin <mst@redhat.com>
Thu, 13 Feb 2014 09:42:05 +0000 (11:42 +0200)
committerJiri Slaby <jslaby@suse.cz>
Wed, 26 Feb 2014 09:22:52 +0000 (10:22 +0100)
commit1d2e001bfa119126098310d0cb860fdc8a2c6cf8
treed2c41c3a945c6f834caddad64cf93163b45b4365
parent917cc7f09179ad3e0291ace1b56dd5b9788d8131
vhost: fix ref cnt checking deadlock

[ Upstream commit 0ad8b480d6ee916aa84324f69acf690142aecd0e ]

vhost checked the counter within the refcnt before decrementing.  It
really wanted to know that it is the one that has the last reference, as
a way to batch freeing resources a bit more efficiently.

Note: we only let refcount go to 0 on device release.

This works well but we now access the ref counter twice so there's a
race: all users might see a high count and decide to defer freeing
resources.
In the end no one initiates freeing resources until the last reference
is gone (which is on VM shotdown so might happen after a looooong time).

Let's do what we probably should have done straight away:
switch from kref to plain atomic, documenting the
semantics, return the refcount value atomically after decrement,
then use that to avoid the deadlock.

Reported-by: Qin Chuanyu <qinchuanyu@huawei.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
drivers/vhost/net.c