[Spice-devel] [PATCH] Fix vm which uses es1370 sound card crashes when disconnecting or rebooting

徐舫 xufango at gmail.com
Tue Nov 27 00:02:18 PST 2012


hello, everybody:

-------------------------------------------------------------------------------------------------------------------------
Problem description
-------------------------------------------------------------------------------------------------------------------------

When starting a windows vm useing es1370 sound card like this:

/usr/libexec/qemu-kvm -enable-kvm win7-child.img -spice
port=5930,disable-ticketing -m 2048 -vga qxl -usbdevice tablet -device
ES1370,id=sound0,bus=pci.0,addr=0x3

use any spice client to connect this vm, the first time, the sound
channel may have not connected(the vm is still booting).

But after that, if the sound channel was connected,  disconnect to or
reboot the vm, the vm would crash.


The spice log shows:

red_channel_remove_client: ASSERT pthread_equal(pthread_self(),
rcc->channel->thread_id) failed


The gdb stack is :

#0  0x00007ffff4cb4885 in raise () from /lib64/libc.so.6
#1  0x00007ffff4cb6065 in abort () from /lib64/libc.so.6
#2  0x00007ffff54d3283 in ring_remove (rcc=0x7ffff9b25450) at
../common/ring.h:84
#3  red_channel_remove_client (rcc=0x7ffff9b25450) at red_channel.c:1183
#4  0x00007ffff54d5195 in red_channel_client_disconnect_dummy
(rcc=0x7ffff9b25450) at red_channel.c:1201
#5  red_channel_client_disconnect (rcc=0x7ffff9b25450) at red_channel.c:1212
#6  0x00007ffff55011fb in snd_disconnect_channel (channel=0x7ffff9b50010) at
snd_worker.c:222
#7  0x00007ffff5501c9e in snd_receive (data=0x7ffff9b50010) at snd_worker.c:475
#8  0x00007ffff5501df0 in snd_event (fd=<value optimized out>, event=<value
optimized out>, data=<value optimized out>)  at snd_worker.c:505
#9  0x00007ffff7deb76f in main_loop_wait (timeout=1000) at
/usr/src/debug/qemu-kvm-0.12.1.2/vl.c:3990
#10 0x00007ffff7e0d01a in kvm_main_loop () at
/usr/src/debug/qemu-kvm-0.12.1.2/qemu-kvm.c:2244
#11 0x00007ffff7dee2bc in main_loop (argc=20, argv=<value optimized out>,
envp=<value optimized out>) at /usr/src/debug/qemu-kvm-0.12.1.2/vl.c:4202
#12 main (argc=20, argv=<value optimized out>, envp=<value optimized out>) at
/usr/src/debug/qemu-kvm-0.12.1.2/vl.c:6427


Yes, the red_channel_remove_client calls:

ASSERT( pthread_equal(pthread_self(), rcc->channel->thread_id) )



-------------------------------------------------------------------------------------------------------------------------
Problem analysis
-------------------------------------------------------------------------------------------------------------------------

I found that the channel type is 6, created in snd_attach_record.

red_channel_create_dummy(sizeof(RedChannel), SPICE_CHANNEL_RECORD, 0)


In my running session, snd_attach_record is called in the thread  11 :

12 Thread 0x7fff339fc700 (LWP 8213)  0x00007ffff54ca3ed in glz_rgb32_do_match
(encoder=0x7fffc008ac00, seg_idx=7,     from=<value optimized out>,
copied=<value optimized out>) at glz_encode_tmpl.c:234

* 11 Thread 0x7fffcdbf5700 (LWP 8204)  red_channel_create_dummy (size=320,
type=6, id=0) at red_channel.c:676

  10 Thread 0x7fffce5f6700 (LWP 8203)  0x00007ffff7750ff4 in __lll_lock_wait ()
from /lib64/libpthread.so.0
 ......

  1 Thread 0x7ffff7d64940 (LWP 8036)  0x00007ffff7750ff4 in __lll_lock_wait ()
from /lib64/libpthread.so.0


The gdb call stack is :

#0  red_channel_create_dummy (size=<value optimized out>, type=6, id=0) at
red_channel.c:695
#1  0x00007ffff5501449 in snd_attach_record (sin=0x7fffbc00a0a0) at
snd_worker.c:1503
#2  0x00007ffff54f4f3e in spice_server_add_interface (s=<value optimized out>,
sin=0x7fffbc00a0a0) at reds.c:3460
#3  0x00007ffff7e7fd88 in line_in_init (hw=0x7fffbc00a030, as=<value optimized
out>) at audio/spiceaudio.c:226
#4  0x00007ffff7e7c466 in audio_pcm_hw_add_new_in (as=0x7fffcdbf49e0) at
audio/audio_template.h:274
#5  0x00007ffff7e7ca9a in audio_pcm_hw_add_in (card=0x7ffff9175280, sw=<value
optimized out>, name=0x7ffff7faf5f0 "es1370.adc",
callback_opaque=0x7ffff9175010,
callback_fn=0x7ffff7f3db20<es1370_adc_callback>, as=0x7fffcdbf4a70)
at audio/audio_template.h:316
#6  audio_pcm_create_voice_pair_in (card=0x7ffff9175280, sw=<value
optimized out>, name=0x7ffff7faf5f0 "es1370.adc",
callback_opaque=0x7ffff9175010, callback_fn=0x7ffff7f3db20
<es1370_adc_callback>, as=0x7fffcdbf4a70) at
audio/audio_template.h:358
#7  AUD_open_in (card=0x7ffff9175280, sw=<value optimized out>,
name=0x7ffff7faf5f0 "es1370.adc", callback_opaque=0x7ffff9175010,
callback_fn=0x7ffff7f3db20 <es1370_adc_callback>, as=0x7fffcdbf4a70)
at audio/audio_template.h:481
#8  0x00007ffff7f3d607 in es1370_update_voices (s=0x7ffff9175038,
ctl=671088641, sctl=0) at /usr/src/debug/qemu-kvm-0.12.1.2/hw/es1370.c:427
#9  0x00007ffff7e0eeb5 in kvm_handle_io (env=0x7ffff90a2010) at
/usr/src/debug/qemu-kvm-0.12.1.2/kvm-all.c:587
#10 kvm_run (env=0x7ffff90a2010) at
/usr/src/debug/qemu-kvm-0.12.1.2/qemu-kvm.c:1048
#11 0x00007ffff7e0ef69 in kvm_cpu_exec (env=<value optimized out>) at
/usr/src/debug/qemu-kvm-0.12.1.2/qemu-kvm.c:1743
#12 0x00007ffff7e0fe4d in kvm_main_loop_cpu (_env=0x7ffff90a2010) at
/usr/src/debug/qemu-kvm-0.12.1.2/qemu-kvm.c:2004
#13 ap_main_loop (_env=0x7ffff90a2010) at
/usr/src/debug/qemu-kvm-0.12.1.2/qemu-kvm.c:2060
#14 0x00007ffff774a7f1 in start_thread () from /lib64/libpthread.so.0
#15 0x00007ffff4d6770d in clone () from /lib64/libc.so.6


But when calling the snd_disconnect_channel, the thread is 1:

12 Thread 0x7fff339fc700 (LWP 8213)  0x00007ffff4d67d03 in epoll_wait () from
/lib64/libc.so.6
  11 Thread 0x7fffcdbf5700 (LWP 8204)  0x00007ffff7750ff4 in __lll_lock_wait ()
from /lib64/libpthread.so.0
......
  2 Thread 0x7fffef78a700 (LWP 8096)  0x00007ffff774e75b in
pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
* 1 Thread 0x7ffff7d64940 (LWP 8036)  0x00007ffff4cb4885 in raise () from
/lib64/libc.so.6



So, it is obviously that thread id of creating and destroying
SPICE_CHANNEL_RECORD channel is not equal.


-------------------------------------------------------------------------------------------------------------------------
Patch
-------------------------------------------------------------------------------------------------------------------------

diff --git a/server/red_channel.c b/server/red_channel.c
index b52f9e6..81f09ce 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -1424,6 +1424,15 @@ static void
red_channel_remove_client(RedChannelClient *rcc)
     // TODO: should we set rcc->channel to NULL???
 }

+static void red_channel_remove_client_dummy(RedChannelClient *rcc)
+{
+    ring_remove(&rcc->channel_link);
+    spice_assert(rcc->channel->clients_num > 0);
+    rcc->channel->clients_num--;
+    // TODO: should we set rcc->channel to NULL???
+}
+
 static void red_client_remove_channel(RedChannelClient *rcc)
 {
     pthread_mutex_lock(&rcc->client->lock);
@@ -1436,7 +1445,7 @@ static void
red_channel_client_disconnect_dummy(RedChannelClient *rcc)
 {
     spice_assert(rcc->dummy);
     if (ring_item_is_linked(&rcc->channel_link)) {
-        red_channel_remove_client(rcc);
+        red_channel_remove_client_dummy(rcc);
     }
     rcc->dummy_connected = FALSE;
 }




-- 
Xu Fang
School of Computer Science and Engineering, Beihang University
State Key Laboratory of Virtual Reality Technology and Systems,
Beijing,P.R.China
Address:
    Beihang University
    Room727, NewMain Building,
    No. 35 Xueyuan Road, Haidian Distric,
    Beijing,P.R.China,100191


More information about the Spice-devel mailing list