qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] fixing qemu-0.1X endless loop in qcow2_alloc_cluster_offset
@ 2012-05-13  8:03 Zhouyi Zhou
  2012-05-14 12:20 ` Kevin Wolf
  0 siblings, 1 reply; 10+ messages in thread
From: Zhouyi Zhou @ 2012-05-13  8:03 UTC (permalink / raw)
  To: qemu-devel

hi all
  
  sometimes, qemu/kvm-0.1x will hang in endless loop in qcow2_alloc_cluster_offset.
  after some investigation, I found that:
  in function posix_aio_process_queue(void *opaque)
440             ret = qemu_paio_error(acb);
441             if (ret == ECANCELED) {
442                 /* remove the request */
443                 *pacb = acb->next;
444                 qemu_aio_release(acb);
445                 result = 1;
446             } else if (ret != EINPROGRESS) {
  in line 444 acb got released but acb->common.opaque does not.
which will be released via guest OS via ide_dma_cancel which 
will in term call qcow_aio_cancel which does not check its argument
is in flight list or not.
  The fix is as follows: (debian 6's qemu-kvm-0.12.5)
#######################################
--- block/qcow2.h~      2010-07-27 08:43:53.000000000 +0800
+++ block/qcow2.h       2012-05-13 15:51:39.000000000 +0800
@@ -143,6 +143,7 @@
     QLIST_HEAD(QCowAioDependencies, QCowAIOCB) dependent_requests;
 
     QLIST_ENTRY(QCowL2Meta) next_in_flight;
+    int inflight;       
 } QCowL2Meta;
--- block/qcow2.c~  2012-05-13 15:57:09.000000000 +0800
+++ block/qcow2.c       2012-05-13 15:57:24.000000000 +0800
@@ -349,6 +349,10 @@
     QCowAIOCB *acb = (QCowAIOCB *)blockacb;
     if (acb->hd_aiocb)
         bdrv_aio_cancel(acb->hd_aiocb);
+    if (acb->l2meta.inflight) {
+        QLIST_REMOVE(&acb->l2meta, next_in_flight);
+       acb->l2meta.inflight = 0;
+    }
     qemu_aio_release(acb);
 }
 
@@ -506,6 +510,7 @@
     acb->n = 0;
     acb->cluster_offset = 0;
     acb->l2meta.nb_clusters = 0;
+    acb->l2meta.inflight = 0;
     QLIST_INIT(&acb->l2meta.dependent_requests);
     return acb;
 }
@@ -534,6 +539,7 @@
     /* Take the request off the list of running requests */
     if (m->nb_clusters != 0) {
         QLIST_REMOVE(m, next_in_flight);
+       m->inflight = 0;
     }
 
     /*
@@ -632,6 +638,7 @@
 fail:
     if (acb->l2meta.nb_clusters != 0) {
         QLIST_REMOVE(&acb->l2meta, next_in_flight);
+       acb->l2meta.inflight  = 0;
     }
 done:
     if (acb->qiov->niov > 1)
--- block/qcow2-cluster.c~      2010-07-27 08:43:53.000000000 +0800
+++ block/qcow2-cluster.c       2012-05-13 15:53:53.000000000 +0800
@@ -827,6 +827,7 @@
     m->offset = offset;
     m->n_start = n_start;
     m->nb_clusters = nb_clusters;
+    m->inflight = 1;
 
 out:
     m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end);

 Thanks for investigation
Zhouyi


-- 
Zhouyi Zhou <yizhouzhou@ict.ac.cn>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-11-09 17:21 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-13  8:03 [Qemu-devel] fixing qemu-0.1X endless loop in qcow2_alloc_cluster_offset Zhouyi Zhou
2012-05-14 12:20 ` Kevin Wolf
2012-06-12 13:33   ` Andreas Färber
2012-06-12 13:44     ` Kevin Wolf
2012-10-12 15:52       ` Andreas Färber
2012-10-15  9:13         ` Kevin Wolf
2012-10-15 14:28           ` Andreas Färber
2012-10-15 14:46             ` Kevin Wolf
2012-10-16  3:32             ` 周洲仪
2012-11-09 17:21           ` Andreas Färber

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).