[Qemu-devel] [PATCH 15/27] buffered_file: unfold migrate_fd_put_ready

2012-07-24 Thread Juan Quintela
We only use it once, just remove the callback indirection.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |5 +
 buffered_file.h |2 --
 migration.c |4 +---
 migration.h |1 +
 4 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index 702a726..4c6a797 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -23,7 +23,6 @@

 typedef struct QEMUFileBuffered
 {
-BufferedPutReadyFunc *put_ready;
 BufferedWaitForUnfreezeFunc *wait_for_unfreeze;
 BufferedCloseFunc *close;
 MigrationState *migration_state;
@@ -128,7 +127,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t 
*buf, int64_t pos, in
 DPRINTF(file is ready\n);
 if (!s-freeze_output  s-bytes_xfer  s-xfer_limit) {
 DPRINTF(notifying client\n);
-s-put_ready(s-migration_state);
+migrate_fd_put_ready(s-migration_state);
 }
 }

@@ -227,7 +226,6 @@ static void buffered_rate_tick(void *opaque)

 QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
   size_t bytes_per_sec,
-  BufferedPutReadyFunc *put_ready,
   BufferedWaitForUnfreezeFunc 
*wait_for_unfreeze,
   BufferedCloseFunc *close)
 {
@@ -237,7 +235,6 @@ QEMUFile *qemu_fopen_ops_buffered(MigrationState 
*migration_state,

 s-migration_state = migration_state;
 s-xfer_limit = bytes_per_sec / 10;
-s-put_ready = put_ready;
 s-wait_for_unfreeze = wait_for_unfreeze;
 s-close = close;

diff --git a/buffered_file.h b/buffered_file.h
index ca7e62d..dd239b3 100644
--- a/buffered_file.h
+++ b/buffered_file.h
@@ -17,13 +17,11 @@
 #include hw/hw.h
 #include migration.h

-typedef void (BufferedPutReadyFunc)(void *opaque);
 typedef void (BufferedWaitForUnfreezeFunc)(void *opaque);
 typedef int (BufferedCloseFunc)(void *opaque);

 QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
   size_t xfer_limit,
-  BufferedPutReadyFunc *put_ready,
   BufferedWaitForUnfreezeFunc 
*wait_for_unfreeze,
   BufferedCloseFunc *close);

diff --git a/migration.c b/migration.c
index fdc570b..a54cd77 100644
--- a/migration.c
+++ b/migration.c
@@ -326,9 +326,8 @@ ssize_t migrate_fd_put_buffer(MigrationState *s, const void 
*data,
 return ret;
 }

-static void migrate_fd_put_ready(void *opaque)
+void migrate_fd_put_ready(MigrationState *s)
 {
-MigrationState *s = opaque;
 int ret;

 if (s-state != MIG_STATE_ACTIVE) {
@@ -439,7 +438,6 @@ void migrate_fd_connect(MigrationState *s)
 s-state = MIG_STATE_ACTIVE;
 s-file = qemu_fopen_ops_buffered(s,
   s-bandwidth_limit,
-  migrate_fd_put_ready,
   migrate_fd_wait_for_unfreeze,
   migrate_fd_close);

diff --git a/migration.h b/migration.h
index eeaa32c..852db51 100644
--- a/migration.h
+++ b/migration.h
@@ -77,6 +77,7 @@ void migrate_fd_connect(MigrationState *s);

 ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data,
   size_t size);
+void migrate_fd_put_ready(MigrationState *s);

 void add_migration_state_change_notifier(Notifier *notify);
 void remove_migration_state_change_notifier(Notifier *notify);
-- 
1.7.10.4




[Qemu-devel] [PATCH 14/27] buffered_file: unfold migrate_fd_put_buffer

2012-07-24 Thread Juan Quintela
We only used it once, just remove the callback indirection

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |7 ++-
 buffered_file.h |2 --
 migration.c |6 ++
 migration.h |3 +++
 4 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index 59d952d..702a726 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -23,7 +23,6 @@

 typedef struct QEMUFileBuffered
 {
-BufferedPutFunc *put_buffer;
 BufferedPutReadyFunc *put_ready;
 BufferedWaitForUnfreezeFunc *wait_for_unfreeze;
 BufferedCloseFunc *close;
@@ -78,8 +77,8 @@ static void buffered_flush(QEMUFileBuffered *s)
 while (s-bytes_xfer  s-xfer_limit  offset  s-buffer_size) {
 ssize_t ret;

-ret = s-put_buffer(s-migration_state, s-buffer + offset,
-s-buffer_size - offset);
+ret = migrate_fd_put_buffer(s-migration_state, s-buffer + offset,
+s-buffer_size - offset);
 if (ret == -EAGAIN) {
 DPRINTF(backend not ready, freezing\n);
 s-freeze_output = 1;
@@ -228,7 +227,6 @@ static void buffered_rate_tick(void *opaque)

 QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
   size_t bytes_per_sec,
-  BufferedPutFunc *put_buffer,
   BufferedPutReadyFunc *put_ready,
   BufferedWaitForUnfreezeFunc 
*wait_for_unfreeze,
   BufferedCloseFunc *close)
@@ -239,7 +237,6 @@ QEMUFile *qemu_fopen_ops_buffered(MigrationState 
*migration_state,

 s-migration_state = migration_state;
 s-xfer_limit = bytes_per_sec / 10;
-s-put_buffer = put_buffer;
 s-put_ready = put_ready;
 s-wait_for_unfreeze = wait_for_unfreeze;
 s-close = close;
diff --git a/buffered_file.h b/buffered_file.h
index 39f7fa0..ca7e62d 100644
--- a/buffered_file.h
+++ b/buffered_file.h
@@ -17,14 +17,12 @@
 #include hw/hw.h
 #include migration.h

-typedef ssize_t (BufferedPutFunc)(void *opaque, const void *data, size_t size);
 typedef void (BufferedPutReadyFunc)(void *opaque);
 typedef void (BufferedWaitForUnfreezeFunc)(void *opaque);
 typedef int (BufferedCloseFunc)(void *opaque);

 QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
   size_t xfer_limit,
-  BufferedPutFunc *put_buffer,
   BufferedPutReadyFunc *put_ready,
   BufferedWaitForUnfreezeFunc 
*wait_for_unfreeze,
   BufferedCloseFunc *close);
diff --git a/migration.c b/migration.c
index 4be047a..fdc570b 100644
--- a/migration.c
+++ b/migration.c
@@ -303,10 +303,9 @@ static void migrate_fd_put_notify(void *opaque)
 }
 }

-static ssize_t migrate_fd_put_buffer(void *opaque, const void *data,
- size_t size)
+ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data,
+  size_t size)
 {
-MigrationState *s = opaque;
 ssize_t ret;

 if (s-state != MIG_STATE_ACTIVE) {
@@ -440,7 +439,6 @@ void migrate_fd_connect(MigrationState *s)
 s-state = MIG_STATE_ACTIVE;
 s-file = qemu_fopen_ops_buffered(s,
   s-bandwidth_limit,
-  migrate_fd_put_buffer,
   migrate_fd_put_ready,
   migrate_fd_wait_for_unfreeze,
   migrate_fd_close);
diff --git a/migration.h b/migration.h
index a9852fc..eeaa32c 100644
--- a/migration.h
+++ b/migration.h
@@ -75,6 +75,9 @@ void migrate_fd_error(MigrationState *s);

 void migrate_fd_connect(MigrationState *s);

+ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data,
+  size_t size);
+
 void add_migration_state_change_notifier(Notifier *notify);
 void remove_migration_state_change_notifier(Notifier *notify);
 bool migration_is_active(MigrationState *);
-- 
1.7.10.4




[Qemu-devel] [PATCH 18/27] buffered_file: We can access directly to bandwidth_limit

2012-07-24 Thread Juan Quintela
Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |5 ++---
 buffered_file.h |3 +--
 migration.c |2 +-
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index 4fca774..43e68b6 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -222,15 +222,14 @@ static void buffered_rate_tick(void *opaque)
 buffered_put_buffer(s, NULL, 0, 0);
 }

-QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
-  size_t bytes_per_sec)
+QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state)
 {
 QEMUFileBuffered *s;

 s = g_malloc0(sizeof(*s));

 s-migration_state = migration_state;
-s-xfer_limit = bytes_per_sec / 10;
+s-xfer_limit = migration_state-bandwidth_limit / 10;

 s-file = qemu_fopen_ops(s, buffered_put_buffer, NULL,
  buffered_close, buffered_rate_limit,
diff --git a/buffered_file.h b/buffered_file.h
index 8a38754..ef010fe 100644
--- a/buffered_file.h
+++ b/buffered_file.h
@@ -17,7 +17,6 @@
 #include hw/hw.h
 #include migration.h

-QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
-  size_t xfer_limit);
+QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state);

 #endif
diff --git a/migration.c b/migration.c
index c639c99..25ea98d 100644
--- a/migration.c
+++ b/migration.c
@@ -433,7 +433,7 @@ void migrate_fd_connect(MigrationState *s)
 int ret;

 s-state = MIG_STATE_ACTIVE;
-s-file = qemu_fopen_ops_buffered(s, s-bandwidth_limit);
+s-file = qemu_fopen_ops_buffered(s);

 DPRINTF(beginning savevm\n);
 ret = qemu_savevm_state_begin(s-file, s-params);
-- 
1.7.10.4




[Qemu-devel] [PATCH 25/27] buffered_file: Unfold the trick to restart generating migration data

2012-07-24 Thread Juan Quintela
This was needed before due to the way that the callbacks worked.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |   17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index de07a05..ac2327b 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -112,14 +112,6 @@ static int buffered_put_buffer(void *opaque, const uint8_t 
*buf, int64_t pos, in

 buffered_flush(s);

-if (pos == 0  size == 0) {
-DPRINTF(file is ready\n);
-if (s-bytes_xfer  s-xfer_limit) {
-DPRINTF(notifying client\n);
-migrate_fd_put_ready(s-migration_state);
-}
-}
-
 return size;
 }

@@ -207,8 +199,15 @@ static void *buffered_file_thread(void *opaque)
 /* usleep expects microseconds */
 usleep((expire_time - current_time)*1000);
 }
-buffered_put_buffer(s, NULL, 0, 0);
+buffered_flush(s);
+
+DPRINTF(file is ready\n);
+if (s-bytes_xfer  s-xfer_limit) {
+DPRINTF(notifying client\n);
+migrate_fd_put_ready(s-migration_state);
+}
 }
+
 g_free(s-buffer);
 g_free(s);
 return NULL;
-- 
1.7.10.4




[Qemu-devel] [PATCH 00/11] Migration next v5

2012-07-24 Thread Juan Quintela
Hi

This series include back xbrle.  In addressed all the review comments
addressed by luiz.

Please, review.

Thanks, Juan.

Juan Quintela (1):
  Restart optimization on stage3 update version

Orit Wasserman (10):
  Add migration capabilities
  Add migrate_set_parameter command
  Add XBZRLE documentation
  Add cache handling functions
  Add uleb encoding/decoding functions
  Add xbzrle_encode_buffer and xbzrle_decode_buffer functions
  Add XBZRLE to ram_save_block and ram_save_live
  Add migrate_set_cachesize command
  Add migration accounting for normal and duplicate pages
  Add XBZRLE statistics

 Makefile.objs |1 +
 arch_init.c   |  263 +++--
 cutils.c  |   42 
 docs/xbzrle.txt   |  136 +++
 hmp-commands.hx   |   36 +++
 hmp.c |   98 +
 hmp.h |3 +
 include/qemu/page_cache.h |   79 ++
 migration.c   |  127 +-
 migration.h   |   21 
 monitor.c |7 ++
 page_cache.c  |  216 +
 qapi-schema.json  |  104 +-
 qemu-common.h |   21 
 qmp-commands.hx   |  127 +-
 savevm.c  |  159 +++
 16 files changed, 1425 insertions(+), 15 deletions(-)
 create mode 100644 docs/xbzrle.txt
 create mode 100644 include/qemu/page_cache.h
 create mode 100644 page_cache.c

-- 
1.7.10.4




[Qemu-devel] [PATCH 04/22] qapi: qapi_visit.py, make code useable as module

2012-07-24 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/qapi_visit.py |  143 +
 1 file changed, 74 insertions(+), 69 deletions(-)

diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
index 04ef7c4..25707f5 100644
--- a/scripts/qapi_visit.py
+++ b/scripts/qapi_visit.py
@@ -224,55 +224,57 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, 
const char *name, Error **e
 ''',
 name=name)
 
-try:
-opts, args = getopt.gnu_getopt(sys.argv[1:], chp:o:,
-   [source, header, prefix=, 
output-dir=])
-except getopt.GetoptError, err:
-print str(err)
-sys.exit(1)
-
-output_dir = 
-prefix = 
-c_file = 'qapi-visit.c'
-h_file = 'qapi-visit.h'
-
-do_c = False
-do_h = False
-
-for o, a in opts:
-if o in (-p, --prefix):
-prefix = a
-elif o in (-o, --output-dir):
-output_dir = a + /
-elif o in (-c, --source):
+def main(argv=[]):
+try:
+opts, args = getopt.gnu_getopt(sys.argv[1:], chp:o:,
+   [source, header, prefix=,
+output-dir=])
+except getopt.GetoptError, err:
+print str(err)
+sys.exit(1)
+
+output_dir = 
+prefix = 
+c_file = 'qapi-visit.c'
+h_file = 'qapi-visit.h'
+
+do_c = False
+do_h = False
+
+for o, a in opts:
+if o in (-p, --prefix):
+prefix = a
+elif o in (-o, --output-dir):
+output_dir = a + /
+elif o in (-c, --source):
+do_c = True
+elif o in (-h, --header):
+do_h = True
+
+if not do_c and not do_h:
 do_c = True
-elif o in (-h, --header):
 do_h = True
 
-if not do_c and not do_h:
-do_c = True
-do_h = True
+c_file = output_dir + prefix + c_file
+h_file = output_dir + prefix + h_file
 
-c_file = output_dir + prefix + c_file
-h_file = output_dir + prefix + h_file
+try:
+os.makedirs(output_dir)
+except os.error, e:
+if e.errno != errno.EEXIST:
+raise
 
-try:
-os.makedirs(output_dir)
-except os.error, e:
-if e.errno != errno.EEXIST:
-raise
-
-def maybe_open(really, name, opt):
-if really:
-return open(name, opt)
-else:
-import StringIO
-return StringIO.StringIO()
+def maybe_open(really, name, opt):
+if really:
+return open(name, opt)
+else:
+import StringIO
+return StringIO.StringIO()
 
-fdef = maybe_open(do_c, c_file, 'w')
-fdecl = maybe_open(do_h, h_file, 'w')
+fdef = maybe_open(do_c, c_file, 'w')
+fdecl = maybe_open(do_h, h_file, 'w')
 
-fdef.write(mcgen('''
+fdef.write(mcgen('''
 /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
 
 /*
@@ -292,7 +294,7 @@ fdef.write(mcgen('''
 ''',
  header=basename(h_file)))
 
-fdecl.write(mcgen('''
+fdecl.write(mcgen('''
 /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
 
 /*
@@ -316,37 +318,40 @@ fdecl.write(mcgen('''
 ''',
   prefix=prefix, guard=guardname(h_file)))
 
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin)
 
-for expr in exprs:
-if expr.has_key('type'):
-ret = generate_visit_struct(expr['type'], expr['data'])
-ret += generate_visit_list(expr['type'], expr['data'])
-fdef.write(ret)
+for expr in exprs:
+if expr.has_key('type'):
+ret = generate_visit_struct(expr['type'], expr['data'])
+ret += generate_visit_list(expr['type'], expr['data'])
+fdef.write(ret)
 
-ret = generate_declaration(expr['type'], expr['data'])
-fdecl.write(ret)
-elif expr.has_key('union'):
-ret = generate_visit_union(expr['union'], expr['data'])
-ret += generate_visit_list(expr['union'], expr['data'])
-fdef.write(ret)
+ret = generate_declaration(expr['type'], expr['data'])
+fdecl.write(ret)
+elif expr.has_key('union'):
+ret = generate_visit_union(expr['union'], expr['data'])
+ret += generate_visit_list(expr['union'], expr['data'])
+fdef.write(ret)
 
-ret = generate_decl_enum('%sKind' % expr['union'], expr['data'].keys())
-ret += generate_declaration(expr['union'], expr['data'])
-fdecl.write(ret)
-elif expr.has_key('enum'):
-ret = generate_visit_enum(expr['enum'], expr['data'])
-fdef.write(ret)
+ret = generate_decl_enum('%sKind' % expr['union'], 
expr['data'].keys())
+ret += generate_declaration(expr['union'], expr['data'])
+fdecl.write(ret)
+elif expr.has_key('enum'):
+ret = generate_visit_enum(expr['enum'], expr['data'])
+fdef.write(ret)
 
-ret = generate_decl_enum(expr['enum'], expr['data'])
-fdecl.write(ret)
+ret = generate_decl_enum(expr['enum'], 

[Qemu-devel] [PATCH 07/22] qapi: qapi_visit.py, support generating static functions

2012-07-24 Thread Michael Roth
qidl embeds visitor code into object files rather than linking against
seperate files, so allow for static declarations when we're using
qapi_visit.py as a library as we do with qidl.py

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 scripts/qapi_visit.py |   51 -
 1 file changed, 33 insertions(+), 18 deletions(-)

diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
index bf93bfe..864acb2 100644
--- a/scripts/qapi_visit.py
+++ b/scripts/qapi_visit.py
@@ -139,13 +139,16 @@ visit_end_optional(m, err);
 ''')
 return ret
 
-def generate_visit_struct(name, members):
+def generate_visit_struct(name, members, static=False):
+ret_type = void
+if static:
+ret_type = static  + ret_type
 ret = mcgen('''
 
-void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error 
**errp)
+%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char 
*name, Error **errp)
 {
 ''',
-name=name)
+name=name, ret_type=ret_type)
 
 push_indent()
 ret += generate_visit_struct_body(, name, members)
@@ -156,10 +159,13 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, 
const char *name, Error **
 ''')
 return ret
 
-def generate_visit_list(name, members):
+def generate_visit_list(name, members, static=False):
+ret_type = void
+if static:
+ret_type = static  + ret_type
 return mcgen('''
 
-void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
*name, Error **errp)
+%(ret_type)s visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const 
char *name, Error **errp)
 {
 GenericList *i, **prev = (GenericList **)obj;
 Error *err = NULL;
@@ -181,19 +187,22 @@ void visit_type_%(name)sList(Visitor *m, %(name)sList ** 
obj, const char *name,
 }
 }
 ''',
-name=name)
+name=name, ret_type=ret_type)
 
-def generate_visit_enum(name, members):
+def generate_visit_enum(name, members, static=False):
+ret_type = void
+if static:
+ret_type = static  + ret_type
 return mcgen('''
 
-void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error 
**errp)
+%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, 
Error **errp)
 {
 visit_type_enum(m, (int *)obj, %(name)s_lookup, %(name)s, name, errp);
 }
 ''',
- name=name)
+ name=name, ret_type=ret_type)
 
-def generate_visit_union(name, members):
+def generate_visit_union(name, members, static=False):
 ret = generate_visit_enum('%sKind' % name, members.keys())
 
 ret += mcgen('''
@@ -250,27 +259,33 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, 
const char *name, Error **
 
 return ret
 
-def generate_declaration(name, members, genlist=True):
+def generate_declaration(name, members, genlist=True, static=False):
+ret_type = void
+if static:
+ret_type = static  + ret_type
 ret = mcgen('''
 
-void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error 
**errp);
+%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char 
*name, Error **errp);
 ''',
-name=name)
+name=name, ret_type=ret_type)
 
 if genlist:
 ret += mcgen('''
-void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
*name, Error **errp);
+%(ret_type)s visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const 
char *name, Error **errp);
 ''',
- name=name)
+ name=name, ret_type=ret_type)
 
 return ret
 
-def generate_decl_enum(name, members, genlist=True):
+def generate_decl_enum(name, members, genlist=True, static=False):
+ret_type = void
+if static:
+ret_type = static  + ret_type
 return mcgen('''
 
-void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error 
**errp);
+%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, 
Error **errp);
 ''',
-name=name)
+name=name, ret_type=ret_type)
 
 def main(argv=[]):
 try:
-- 
1.7.9.5




[Qemu-devel] [PATCH 09/11] Add migration accounting for normal and duplicate pages

2012-07-24 Thread Juan Quintela
From: Orit Wasserman owass...@redhat.com

Signed-off-by: Benoit Hudzia benoit.hud...@sap.com
Signed-off-by: Petter Svard pett...@cs.umu.se
Signed-off-by: Aidan Shribman aidan.shrib...@sap.com
Signed-off-by: Orit Wasserman owass...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c  |   38 ++
 migration.c  |   10 ++
 migration.h  |5 +
 qapi-schema.json |8 ++--
 qmp-commands.hx  |2 ++
 5 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 69a39cb..12afc46 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -205,6 +205,40 @@ int64_t xbzrle_cache_resize(int64_t new_size)
 return pow2floor(new_size);
 }

+/* accounting for migration statistics */
+typedef struct AccountingInfo {
+uint64_t dup_pages;
+uint64_t norm_pages;
+uint64_t iterations;
+} AccountingInfo;
+
+static AccountingInfo acct_info;
+
+static void acct_clear(void)
+{
+memset(acct_info, 0, sizeof(acct_info));
+}
+
+uint64_t dup_mig_bytes_transferred(void)
+{
+return acct_info.dup_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t dup_mig_pages_transferred(void)
+{
+return acct_info.dup_pages;
+}
+
+uint64_t norm_mig_bytes_transferred(void)
+{
+return acct_info.norm_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t norm_mig_pages_transferred(void)
+{
+return acct_info.norm_pages;
+}
+
 static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
 int cont, int flag)
 {
@@ -307,6 +341,7 @@ static int ram_save_block(QEMUFile *f)
 p = memory_region_get_ram_ptr(mr) + offset;

 if (is_dup_page(p)) {
+acct_info.dup_pages++;
 save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
 qemu_put_byte(f, *p);
 bytes_sent = 1;
@@ -322,6 +357,7 @@ static int ram_save_block(QEMUFile *f)
 save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
 bytes_sent = TARGET_PAGE_SIZE;
+acct_info.norm_pages++;
 }

 /* if page is unmodified, continue to the next */
@@ -443,6 +479,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 }
 XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
 XBZRLE.current_buf = g_malloc(TARGET_PAGE_SIZE);
+acct_clear();
 }

 QLIST_FOREACH(block, ram_list.blocks, next) {
@@ -490,6 +527,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 break;
 }
 bytes_transferred += bytes_sent;
+acct_info.iterations++;
 /* we want to check in the 1st loop, just in case it was the 1st time
and we had to sync the dirty bitmap.
qemu_get_clock_ns() is a bit expensive, so we only check each some
diff --git a/migration.c b/migration.c
index 9b0e1fa..cae444c 100644
--- a/migration.c
+++ b/migration.c
@@ -156,6 +156,8 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 info-ram-total = ram_bytes_total();
 info-ram-total_time = qemu_get_clock_ms(rt_clock)
 - s-total_time;
+info-ram-duplicate = dup_mig_pages_transferred();
+info-ram-normal = norm_mig_pages_transferred();

 if (blk_mig_active()) {
 info-has_disk = true;
@@ -168,6 +170,14 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 case MIG_STATE_COMPLETED:
 get_capabilities(s, info);

+info-has_ram = true;
+info-ram = g_malloc0(sizeof(*info-ram));
+info-ram-transferred = ram_bytes_transferred();
+info-ram-remaining = ram_bytes_remaining();
+info-ram-total = ram_bytes_total();
+info-ram-duplicate = dup_mig_pages_transferred();
+info-ram-normal = norm_mig_pages_transferred();
+
 info-has_status = true;
 info-status = g_strdup(completed);

diff --git a/migration.h b/migration.h
index 337e225..e4a7cd7 100644
--- a/migration.h
+++ b/migration.h
@@ -87,6 +87,11 @@ uint64_t ram_bytes_total(void);

 extern SaveVMHandlers savevm_ram_handlers;

+uint64_t dup_mig_bytes_transferred(void);
+uint64_t dup_mig_pages_transferred(void);
+uint64_t norm_mig_bytes_transferred(void);
+uint64_t norm_mig_pages_transferred(void);
+
 /**
  * @migrate_add_blocker - prevent migration from proceeding
  *
diff --git a/qapi-schema.json b/qapi-schema.json
index 0b5ccae..8676c1d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -264,11 +264,15 @@
 #migration has ended, it returns the total migration
 #time. (since 1.2)
 #
-# Since: 0.14.0.
+# @duplicate: #optional, number of duplicate pages (since 1.2)
+#
+# @normal : #optional, number of normal pages (since 1.2)
+#
+# Since: 0.14.0
 ##
 { 'type': 'MigrationStats',
   'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' ,
-   'total_time': 'int' } }
+   'total_time': 'int', 

[Qemu-devel] [PATCH 20/27] migration: make qemu_fopen_ops_buffered() return void

2012-07-24 Thread Juan Quintela
We want the file assignment to happen before the thread is created to
avoid locking, so we just do it before creating the thread.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |   13 ++---
 buffered_file.h |2 +-
 migration.c |2 +-
 migration.h |1 +
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index 0021b30..94830fa 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -33,7 +33,6 @@ typedef struct QEMUFileBuffered
 size_t buffer_size;
 size_t buffer_capacity;
 QemuThread thread;
-bool complete;
 } QEMUFileBuffered;

 #ifdef DEBUG_BUFFERED_FILE
@@ -149,7 +148,7 @@ static int buffered_close(void *opaque)
 }

 ret = migrate_fd_close(s-migration_state);
-s-complete = true;
+s-migration_state-complete = true;
 return ret;
 }

@@ -211,7 +210,7 @@ static void *buffered_file_thread(void *opaque)
 while(true) {
 int64_t current_time = qemu_get_clock_ms(rt_clock);

-if (s-complete) {
+if (s-migration_state-complete) {
 break;
 }
 if (s-freeze_output) {
@@ -234,7 +233,7 @@ static void *buffered_file_thread(void *opaque)
 return NULL;
 }

-QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state)
+void qemu_fopen_ops_buffered(MigrationState *migration_state)
 {
 QEMUFileBuffered *s;

@@ -242,15 +241,15 @@ QEMUFile *qemu_fopen_ops_buffered(MigrationState 
*migration_state)

 s-migration_state = migration_state;
 s-xfer_limit = migration_state-bandwidth_limit / 10;
-s-complete = false;
+s-migration_state-complete = false;

 s-file = qemu_fopen_ops(s, buffered_put_buffer, NULL,
  buffered_close, buffered_rate_limit,
  buffered_set_rate_limit,
 buffered_get_rate_limit);

+migration_state-file = s-file;
+
 qemu_thread_create(s-thread, buffered_file_thread, s,
QEMU_THREAD_DETACHED);
-
-return s-file;
 }
diff --git a/buffered_file.h b/buffered_file.h
index ef010fe..8a246fd 100644
--- a/buffered_file.h
+++ b/buffered_file.h
@@ -17,6 +17,6 @@
 #include hw/hw.h
 #include migration.h

-QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state);
+void qemu_fopen_ops_buffered(MigrationState *migration_state);

 #endif
diff --git a/migration.c b/migration.c
index 25ea98d..cd1c11f 100644
--- a/migration.c
+++ b/migration.c
@@ -433,7 +433,7 @@ void migrate_fd_connect(MigrationState *s)
 int ret;

 s-state = MIG_STATE_ACTIVE;
-s-file = qemu_fopen_ops_buffered(s);
+qemu_fopen_ops_buffered(s);

 DPRINTF(beginning savevm\n);
 ret = qemu_savevm_state_begin(s-file, s-params);
diff --git a/migration.h b/migration.h
index f3a684a..a05795b 100644
--- a/migration.h
+++ b/migration.h
@@ -42,6 +42,7 @@ struct MigrationState
 int64_t total_time;
 bool enabled_capabilities[MIGRATION_CAPABILITY_MAX];
 int64_t xbzrle_cache_size;
+bool complete;
 };

 void process_incoming_migration(QEMUFile *f);
-- 
1.7.10.4




[Qemu-devel] [PATCH 10/27] Separate migration bitmap

2012-07-24 Thread Juan Quintela
This patch creates a migration bitmap, which is periodically kept in
sync with the qemu bitmap. A separate copy of the dirty bitmap for the
migration limits the amount of concurrent access to the qemu bitmap
from iothread and migration thread (which requires taking the big
lock).

We use the qemu bitmap type.  We have to undo the dirty_pages
counting optimization on the general dirty bitmap and do the counting
optimization with the migration local bitmap.

Signed-off-by: Umesh Deshpande udesh...@redhat.com
Signed-off-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |   57 +++
 cpu-all.h   |1 -
 exec-obsolete.h |   10 --
 3 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index d21b2a3..72345c3 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -31,6 +31,8 @@
 #include config.h
 #include monitor.h
 #include sysemu.h
+#include bitops.h
+#include bitmap.h
 #include arch_init.h
 #include audio/audio.h
 #include hw/pc.h
@@ -341,35 +343,54 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
*current_data,
 static RAMBlock *last_block;
 static ram_addr_t last_offset;
 static uint32_t last_version;
+static unsigned long *migration_bitmap;
+static uint64_t migration_dirty_pages;

 static inline bool migration_bitmap_test_and_reset_dirty(MemoryRegion *mr,
  ram_addr_t offset)
 {
-bool ret = memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE,
-   DIRTY_MEMORY_MIGRATION);
+bool ret;
+int nr = (mr-ram_addr + offset)  TARGET_PAGE_BITS;
+
+ret = test_and_clear_bit(nr, migration_bitmap);

 if (ret) {
-memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE,
-  DIRTY_MEMORY_MIGRATION);
+migration_dirty_pages--;
 }
 return ret;
 }

-static inline void migration_bitmap_set_dirty(MemoryRegion *mr, int length)
+static inline bool migration_bitmap_set_dirty(MemoryRegion *mr,
+  ram_addr_t offset)
 {
-ram_addr_t addr;
+bool ret;
+int nr = (mr-ram_addr + offset)  TARGET_PAGE_BITS;

-for (addr = 0; addr  length; addr += TARGET_PAGE_SIZE) {
-if (!memory_region_get_dirty(mr, addr, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION)) {
-memory_region_set_dirty(mr, addr, TARGET_PAGE_SIZE);
-}
+ret = test_and_set_bit(nr, migration_bitmap);
+
+if (!ret) {
+migration_dirty_pages++;
 }
+return ret;
 }

 static void migration_bitmap_sync(void)
 {
+RAMBlock *block;
+ram_addr_t addr;
+
 memory_global_sync_dirty_bitmap(get_system_memory());
+
+QLIST_FOREACH(block, ram_list.blocks, next) {
+for (addr = 0; addr  block-length; addr += TARGET_PAGE_SIZE) {
+if (memory_region_get_dirty(block-mr, addr, TARGET_PAGE_SIZE,
+DIRTY_MEMORY_MIGRATION)) {
+migration_bitmap_set_dirty(block-mr, addr);
+}
+}
+memory_region_reset_dirty(block-mr, 0, block-length,
+  DIRTY_MEMORY_MIGRATION);
+}
 }


@@ -447,7 +468,7 @@ static uint64_t bytes_transferred;

 static ram_addr_t ram_save_remaining(void)
 {
-return ram_list.dirty_pages;
+return migration_dirty_pages;
 }

 uint64_t ram_bytes_remaining(void)
@@ -532,6 +553,11 @@ static void reset_ram_globals(void)
 static int ram_save_setup(QEMUFile *f, void *opaque)
 {
 RAMBlock *block;
+int64_t ram_pages = last_ram_offset()  TARGET_PAGE_BITS;
+
+migration_bitmap = bitmap_new(ram_pages);
+bitmap_set(migration_bitmap, 0, ram_pages);
+migration_dirty_pages = ram_pages;

 qemu_mutex_lock_ramlist();

@@ -551,10 +577,6 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 acct_clear();
 }

-QLIST_FOREACH(block, ram_list.blocks, next) {
-migration_bitmap_set_dirty(block-mr, block-length);
-}
-
 memory_global_dirty_log_start();

 qemu_put_be64(f, ram_bytes_total() | RAM_SAVE_FLAG_MEM_SIZE);
@@ -669,6 +691,9 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
 qemu_mutex_unlock_ramlist();
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);

+g_free(migration_bitmap);
+migration_bitmap = NULL;
+
 return 0;
 }

diff --git a/cpu-all.h b/cpu-all.h
index 45290b7..88ad1ba 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -495,7 +495,6 @@ typedef struct RAMList {
 QLIST_HEAD(, RAMBlock) blocks_mru;
 /* Protected by the ramlist lock.  */
 QLIST_HEAD(, RAMBlock) blocks;
-uint64_t dirty_pages;
 } RAMList;
 extern RAMList ram_list;

diff --git a/exec-obsolete.h b/exec-obsolete.h
index c099256..f8ffce6 100644
--- a/exec-obsolete.h
+++ b/exec-obsolete.h
@@ -74,11 +74,6 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t 

[Qemu-devel] [PATCH 03/27] savevm: Factorize ram globals reset in its own function

2012-07-24 Thread Juan Quintela
Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |   12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index f555c27..02d36ce 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -491,6 +491,14 @@ static void ram_migration_cancel(void *opaque)
 migration_end();
 }

+
+static void reset_ram_globals(void)
+{
+last_block = NULL;
+last_offset = 0;
+sort_ram_list();
+}
+
 #define MAX_WAIT 50 /* ms, half buffered_file limit */

 static int ram_save_setup(QEMUFile *f, void *opaque)
@@ -499,9 +507,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 RAMBlock *block;

 bytes_transferred = 0;
-last_block = NULL;
-last_offset = 0;
-sort_ram_list();
+reset_ram_globals();

 if (migrate_use_xbzrle()) {
 XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
-- 
1.7.10.4




[Qemu-devel] [PATCH 06/27] ram: introduce migration_bitmap_set_dirty()

2012-07-24 Thread Juan Quintela
It just marks a region of memory as dirty.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |   20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 5a97710..b47bf05 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -342,6 +342,18 @@ static RAMBlock *last_block;
 static ram_addr_t last_offset;
 static uint32_t last_version;

+static inline void migration_bitmap_set_dirty(MemoryRegion *mr, int length)
+{
+ram_addr_t addr;
+
+for (addr = 0; addr  length; addr += TARGET_PAGE_SIZE) {
+if (!memory_region_get_dirty(mr, addr, TARGET_PAGE_SIZE,
+ DIRTY_MEMORY_MIGRATION)) {
+memory_region_set_dirty(mr, addr, TARGET_PAGE_SIZE);
+}
+}
+}
+
 /*
  * ram_save_block: Writes a page of memory to the stream f
  *
@@ -504,7 +516,6 @@ static void reset_ram_globals(void)

 static int ram_save_setup(QEMUFile *f, void *opaque)
 {
-ram_addr_t addr;
 RAMBlock *block;

 qemu_mutex_lock_ramlist();
@@ -526,12 +537,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 }

 QLIST_FOREACH(block, ram_list.blocks, next) {
-for (addr = 0; addr  block-length; addr += TARGET_PAGE_SIZE) {
-if (!memory_region_get_dirty(block-mr, addr, TARGET_PAGE_SIZE,
- DIRTY_MEMORY_MIGRATION)) {
-memory_region_set_dirty(block-mr, addr, TARGET_PAGE_SIZE);
-}
-}
+migration_bitmap_set_dirty(block-mr, block-length);
 }

 memory_global_dirty_log_start();
-- 
1.7.10.4




[Qemu-devel] [PATCH 08/27] ram: Export last_ram_offset()

2012-07-24 Thread Juan Quintela
Is the only way of knowing the RAM size.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 cpu-all.h |2 ++
 exec.c|2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/cpu-all.h b/cpu-all.h
index 0ff452f..45290b7 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -518,6 +518,8 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 void qemu_mutex_lock_ramlist(void);
 void qemu_mutex_unlock_ramlist(void);

+ram_addr_t last_ram_offset(void);
+
 int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 uint8_t *buf, int len, int is_write);

diff --git a/exec.c b/exec.c
index 53da253..1a98621 100644
--- a/exec.c
+++ b/exec.c
@@ -2481,7 +2481,7 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
 return offset;
 }

-static ram_addr_t last_ram_offset(void)
+ram_addr_t last_ram_offset(void)
 {
 RAMBlock *block;
 ram_addr_t last = 0;
-- 
1.7.10.4




[Qemu-devel] [PATCH 02/27] split MRU ram list

2012-07-24 Thread Juan Quintela
From: Paolo Bonzini pbonz...@redhat.com

Outside the execution threads the normal, non-MRU-ized order of
the RAM blocks should always be enough.  So manage two separate
lists, which will have separate locking rules.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 cpu-all.h |4 +++-
 exec.c|   16 +++-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 82ba1d7..ca3bb24 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -476,8 +476,9 @@ typedef struct RAMBlock {
 ram_addr_t offset;
 ram_addr_t length;
 uint32_t flags;
-char idstr[256];
+QLIST_ENTRY(RAMBlock) next_mru;
 QLIST_ENTRY(RAMBlock) next;
+char idstr[256];
 #if defined(__linux__)  !defined(TARGET_S390X)
 int fd;
 #endif
@@ -485,6 +486,7 @@ typedef struct RAMBlock {

 typedef struct RAMList {
 uint8_t *phys_dirty;
+QLIST_HEAD(, RAMBlock) blocks_mru;
 QLIST_HEAD(, RAMBlock) blocks;
 uint64_t dirty_pages;
 } RAMList;
diff --git a/exec.c b/exec.c
index feb4795..afc472f 100644
--- a/exec.c
+++ b/exec.c
@@ -112,7 +112,10 @@ static uint8_t *code_gen_ptr;
 int phys_ram_fd;
 static int in_migration;

-RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
+RAMList ram_list = {
+.blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks),
+.blocks_mru = QLIST_HEAD_INITIALIZER(ram_list.blocks_mru)
+};

 static MemoryRegion *system_memory;
 static MemoryRegion *system_io;
@@ -2550,6 +2553,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void 
*host,
 new_block-length = size;

 QLIST_INSERT_HEAD(ram_list.blocks, new_block, next);
+QLIST_INSERT_HEAD(ram_list.blocks_mru, new_block, next_mru);

 ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
last_ram_offset()  TARGET_PAGE_BITS);
@@ -2573,6 +2577,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr)
 QLIST_FOREACH(block, ram_list.blocks, next) {
 if (addr == block-offset) {
 QLIST_REMOVE(block, next);
+QLIST_REMOVE(block, next_mru);
 g_free(block);
 return;
 }
@@ -2586,6 +2591,7 @@ void qemu_ram_free(ram_addr_t addr)
 QLIST_FOREACH(block, ram_list.blocks, next) {
 if (addr == block-offset) {
 QLIST_REMOVE(block, next);
+QLIST_REMOVE(block, next_mru);
 if (block-flags  RAM_PREALLOC_MASK) {
 ;
 } else if (mem_path) {
@@ -2690,12 +2696,12 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
 {
 RAMBlock *block;

-QLIST_FOREACH(block, ram_list.blocks, next) {
+QLIST_FOREACH(block, ram_list.blocks_mru, next_mru) {
 if (addr - block-offset  block-length) {
 /* Move this entry to to start of the list.  */
 if (block != QLIST_FIRST(ram_list.blocks)) {
-QLIST_REMOVE(block, next);
-QLIST_INSERT_HEAD(ram_list.blocks, block, next);
+QLIST_REMOVE(block, next_mru);
+QLIST_INSERT_HEAD(ram_list.blocks_mru, block, next_mru);
 }
 if (xen_enabled()) {
 /* We need to check if the requested address is in the RAM
@@ -2790,7 +2796,7 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t 
*ram_addr)
 return 0;
 }

-QLIST_FOREACH(block, ram_list.blocks, next) {
+QLIST_FOREACH(block, ram_list.blocks_mru, next_mru) {
 /* This case append when the block is not mapped. */
 if (block-host == NULL) {
 continue;
-- 
1.7.10.4




[Qemu-devel] [PATCH 21/27] migration: stop all cpus correctly

2012-07-24 Thread Juan Quintela
You can only stop all cpus from the iothread or an vcpu.  As we want
to do it from the migration_thread, we need to do this dance with the
botton handlers.

This patch is a request for ideas.  I can move this function to cpus.c, but
wondered if there is an easy way of doing this?

Signed-off-by: Juan Quintela quint...@redhat.com
---
 migration.c |   46 ++
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/migration.c b/migration.c
index cd1c11f..e3eec97 100644
--- a/migration.c
+++ b/migration.c
@@ -20,6 +20,7 @@
 #include sysemu.h
 #include block.h
 #include qemu_socket.h
+#include qemu-thread.h
 #include block-migration.h
 #include qmp-commands.h

@@ -326,14 +327,37 @@ ssize_t migrate_fd_put_buffer(MigrationState *s, const 
void *data,
 return ret;
 }

+static QemuCond migrate_vm_stop_cond;
+
+static void migrate_vm_stop(void *opaque)
+{
+QEMUBH **bh = opaque;
+vm_stop(RUN_STATE_FINISH_MIGRATE);
+qemu_bh_delete(*bh);
+qemu_cond_signal(migrate_vm_stop_cond);
+}
+
+extern QemuMutex qemu_global_mutex;
+
 void migrate_fd_put_ready(MigrationState *s)
 {
 int ret;
+static bool first_time = true;

 if (s-state != MIG_STATE_ACTIVE) {
 DPRINTF(put_ready returning because of non-active state\n);
 return;
 }
+if (first_time) {
+first_time = false;
+DPRINTF(beginning savevm\n);
+ret = qemu_savevm_state_begin(s-file, s-params);
+if (ret  0) {
+DPRINTF(failed, %d\n, ret);
+migrate_fd_error(s);
+return;
+}
+}

 DPRINTF(iterate\n);
 ret = qemu_savevm_state_iterate(s-file);
@@ -344,7 +368,16 @@ void migrate_fd_put_ready(MigrationState *s)

 DPRINTF(done iterating\n);
 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
-vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+if (old_vm_running) {
+QEMUBH *bh;
+
+qemu_cond_init(migrate_vm_stop_cond);
+bh = qemu_bh_new(migrate_vm_stop, bh);
+qemu_bh_schedule(bh);
+qemu_cond_wait(migrate_vm_stop_cond, qemu_global_mutex);
+} else {
+vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
+}

 if (qemu_savevm_state_complete(s-file)  0) {
 migrate_fd_error(s);
@@ -430,19 +463,8 @@ bool migration_has_failed(MigrationState *s)

 void migrate_fd_connect(MigrationState *s)
 {
-int ret;
-
 s-state = MIG_STATE_ACTIVE;
 qemu_fopen_ops_buffered(s);
-
-DPRINTF(beginning savevm\n);
-ret = qemu_savevm_state_begin(s-file, s-params);
-if (ret  0) {
-DPRINTF(failed, %d\n, ret);
-migrate_fd_error(s);
-return;
-}
-migrate_fd_put_ready(s);
 }

 static MigrationState *migrate_init(const MigrationParams *params)
-- 
1.7.10.4




[Qemu-devel] [PATCH 05/27] protect the ramlist with a separate mutex

2012-07-24 Thread Juan Quintela
From: Umesh Deshpande udesh...@redhat.com

Add the new mutex that protects shared state between ram_save_live
and the iothread.  If the iothread mutex has to be taken together
with the ramlist mutex, the iothread shall always be _outside_.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Umesh Deshpande udesh...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |   10 +-
 cpu-all.h   |9 +
 exec.c  |   23 +--
 3 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 9e05aae..5a97710 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -492,7 +492,6 @@ static void ram_migration_cancel(void *opaque)
 migration_end();
 }

-
 static void reset_ram_globals(void)
 {
 last_block = NULL;
@@ -508,6 +507,8 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 ram_addr_t addr;
 RAMBlock *block;

+qemu_mutex_lock_ramlist();
+
 bytes_transferred = 0;
 reset_ram_globals();

@@ -543,6 +544,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 qemu_put_be64(f, block-length);
 }

+qemu_mutex_unlock_ramlist();
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);

 return 0;
@@ -556,6 +558,8 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 int i;
 uint64_t expected_time;

+qemu_mutex_lock_ramlist();
+
 if (ram_list.version != last_version) {
 reset_ram_globals();
 }
@@ -603,6 +607,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 bwidth = 0.01;
 }

+qemu_mutex_unlock_ramlist();
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);

 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
@@ -623,6 +628,8 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
 {
 memory_global_sync_dirty_bitmap(get_system_memory());

+qemu_mutex_lock_ramlist();
+
 /* try transferring iterative blocks of memory */

 /* flush all remaining blocks regardless of rate limiting */
@@ -638,6 +645,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
 }
 memory_global_dirty_log_stop();

+qemu_mutex_unlock_ramlist();
 qemu_put_be64(f, RAM_SAVE_FLAG_EOS);

 return 0;
diff --git a/cpu-all.h b/cpu-all.h
index 429b2c6..0ff452f 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -22,6 +22,7 @@
 #include qemu-common.h
 #include qemu-tls.h
 #include cpu-common.h
+#include qemu-thread.h

 /* some important defines:
  *
@@ -476,7 +477,9 @@ typedef struct RAMBlock {
 ram_addr_t offset;
 ram_addr_t length;
 uint32_t flags;
+/* Protected by the iothread lock.  */
 QLIST_ENTRY(RAMBlock) next_mru;
+/* Protected by the ramlist lock.  */
 QLIST_ENTRY(RAMBlock) next;
 char idstr[256];
 #if defined(__linux__)  !defined(TARGET_S390X)
@@ -485,9 +488,12 @@ typedef struct RAMBlock {
 } RAMBlock;

 typedef struct RAMList {
+QemuMutex mutex;
+/* Protected by the iothread lock.  */
 uint8_t *phys_dirty;
 uint32_t version;
 QLIST_HEAD(, RAMBlock) blocks_mru;
+/* Protected by the ramlist lock.  */
 QLIST_HEAD(, RAMBlock) blocks;
 uint64_t dirty_pages;
 } RAMList;
@@ -509,6 +515,9 @@ extern int mem_prealloc;
 void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 #endif /* !CONFIG_USER_ONLY */

+void qemu_mutex_lock_ramlist(void);
+void qemu_mutex_unlock_ramlist(void);
+
 int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 uint8_t *buf, int len, int is_write);

diff --git a/exec.c b/exec.c
index ceffa4f..53da253 100644
--- a/exec.c
+++ b/exec.c
@@ -637,6 +637,7 @@ bool tcg_enabled(void)

 void cpu_exec_init_all(void)
 {
+qemu_mutex_init(ram_list.mutex);
 #if !defined(CONFIG_USER_ONLY)
 memory_map_init();
 io_mem_init();
@@ -2367,6 +2368,16 @@ static long gethugepagesize(const char *path)
 return fs.f_bsize;
 }

+void qemu_mutex_lock_ramlist(void)
+{
+qemu_mutex_lock(ram_list.mutex);
+}
+
+void qemu_mutex_unlock_ramlist(void)
+{
+qemu_mutex_unlock(ram_list.mutex);
+}
+
 static void *file_ram_alloc(RAMBlock *block,
 ram_addr_t memory,
 const char *path)
@@ -2504,6 +2515,7 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char 
*name, DeviceState *dev)
 }
 pstrcat(new_block-idstr, sizeof(new_block-idstr), name);

+qemu_mutex_lock_ramlist();
 QLIST_FOREACH(block, ram_list.blocks, next) {
 if (block != new_block  !strcmp(block-idstr, new_block-idstr)) {
 fprintf(stderr, RAMBlock \%s\ already registered, abort!\n,
@@ -2511,6 +2523,7 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char 
*name, DeviceState *dev)
 abort();
 }
 }
+qemu_mutex_unlock_ramlist();
 }

 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
@@ -2521,6 +2534,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void 
*host,
 size = TARGET_PAGE_ALIGN(size);
 new_block = 

[Qemu-devel] [PATCH 10/11] Add XBZRLE statistics

2012-07-24 Thread Juan Quintela
From: Orit Wasserman owass...@redhat.com

Signed-off-by: Benoit Hudzia benoit.hud...@sap.com
Signed-off-by: Petter Svard pett...@cs.umu.se
Signed-off-by: Aidan Shribman aidan.shrib...@sap.com
Signed-off-by: Orit Wasserman owass...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c  |   28 
 hmp.c|   21 +
 migration.c  |   36 +---
 migration.h  |4 
 qapi-schema.json |   27 +--
 qmp-commands.hx  |   33 -
 6 files changed, 139 insertions(+), 10 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index 12afc46..f89908f 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -209,7 +209,11 @@ int64_t xbzrle_cache_resize(int64_t new_size)
 typedef struct AccountingInfo {
 uint64_t dup_pages;
 uint64_t norm_pages;
+uint64_t xbzrle_bytes;
+uint64_t xbzrle_pages;
+uint64_t xbzrle_cache_miss;
 uint64_t iterations;
+uint64_t xbzrle_overflows;
 } AccountingInfo;

 static AccountingInfo acct_info;
@@ -239,6 +243,26 @@ uint64_t norm_mig_pages_transferred(void)
 return acct_info.norm_pages;
 }

+uint64_t xbzrle_mig_bytes_transferred(void)
+{
+return acct_info.xbzrle_bytes;
+}
+
+uint64_t xbzrle_mig_pages_transferred(void)
+{
+return acct_info.xbzrle_pages;
+}
+
+uint64_t xbzrle_mig_pages_cache_miss(void)
+{
+return acct_info.xbzrle_cache_miss;
+}
+
+uint64_t xbzrle_mig_pages_overflow(void)
+{
+return acct_info.xbzrle_overflows;
+}
+
 static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
 int cont, int flag)
 {
@@ -267,6 +291,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
*current_data,
 if (!cache_is_cached(XBZRLE.cache, current_addr)) {
 cache_insert(XBZRLE.cache, current_addr,
  g_memdup(current_data, TARGET_PAGE_SIZE));
+acct_info.xbzrle_cache_miss++;
 return -1;
 }

@@ -284,6 +309,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
*current_data,
 return 0;
 } else if (encoded_len == -1) {
 DPRINTF(Overflow\n);
+acct_info.xbzrle_overflows++;
 /* update data in the cache */
 memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
 return -1;
@@ -301,7 +327,9 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
*current_data,
 qemu_put_byte(f, hdr.xh_flags);
 qemu_put_be16(f, hdr.xh_len);
 qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
+acct_info.xbzrle_pages++;
 bytes_sent = encoded_len + sizeof(hdr);
+acct_info.xbzrle_bytes += bytes_sent;

 return bytes_sent;
 }
diff --git a/hmp.c b/hmp.c
index e0f520d..c141f90 100644
--- a/hmp.c
+++ b/hmp.c
@@ -168,6 +168,27 @@ void hmp_info_migrate(Monitor *mon)
info-disk-total  10);
 }

+if (info-has_xbzrle_cache) {
+monitor_printf(mon, cache size: % PRIu64  bytes\n,
+   info-xbzrle_cache-cache_size);
+if (info-xbzrle_cache-has_xbzrle_bytes) {
+monitor_printf(mon, xbzrle transferred: % PRIu64  kbytes\n,
+   info-xbzrle_cache-xbzrle_bytes  10);
+}
+if (info-xbzrle_cache-has_xbzrle_pages) {
+monitor_printf(mon, xbzrle pages: % PRIu64  pages\n,
+   info-xbzrle_cache-xbzrle_pages);
+}
+if (info-xbzrle_cache-has_xbzrle_cache_miss) {
+monitor_printf(mon, xbzrle cache miss: % PRIu64 \n,
+   info-xbzrle_cache-xbzrle_cache_miss);
+}
+if (info-xbzrle_cache-has_xbzrle_overflow) {
+monitor_printf(mon, xbzrle overflow : % PRIu64 \n,
+   info-xbzrle_cache-xbzrle_overflow);
+}
+}
+
 qapi_free_MigrationInfo(info);
 }

diff --git a/migration.c b/migration.c
index cae444c..4be047a 100644
--- a/migration.c
+++ b/migration.c
@@ -133,6 +133,24 @@ static void get_capabilities(MigrationState *s, 
MigrationInfo *info)
 info-capabilities-next = NULL;
 }
 }
+
+static void get_xbzrle_cache_stats(MigrationInfo *info)
+{
+if (migrate_use_xbzrle()) {
+info-has_xbzrle_cache = true;
+info-xbzrle_cache = g_malloc0(sizeof(*info-xbzrle_cache));
+info-xbzrle_cache-cache_size = migrate_xbzrle_cache_size();
+info-xbzrle_cache-has_xbzrle_bytes = true;
+info-xbzrle_cache-xbzrle_bytes = xbzrle_mig_bytes_transferred();
+info-xbzrle_cache-has_xbzrle_pages = true;
+info-xbzrle_cache-xbzrle_pages = xbzrle_mig_pages_transferred();
+info-xbzrle_cache-has_xbzrle_cache_miss = true;
+info-xbzrle_cache-xbzrle_cache_miss = xbzrle_mig_pages_cache_miss();
+info-xbzrle_cache-has_xbzrle_overflow = true;
+info-xbzrle_cache-xbzrle_overflow = xbzrle_mig_pages_overflow();
+}
+}
+
 MigrationInfo *qmp_query_migrate(Error **errp)
 {
 MigrationInfo *info = 

[Qemu-devel] [PATCH 24/27] migration: take finer locking

2012-07-24 Thread Juan Quintela
Instead of locking the whole migration_thread inside loop, just lock
migration_fd_put_notify, that is what interacts with the rest of the
world.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |2 --
 migration.c |5 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index b5e809c..de07a05 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -207,9 +207,7 @@ static void *buffered_file_thread(void *opaque)
 /* usleep expects microseconds */
 usleep((expire_time - current_time)*1000);
 }
-qemu_mutex_lock_iothread();
 buffered_put_buffer(s, NULL, 0, 0);
-qemu_mutex_unlock_iothread();
 }
 g_free(s-buffer);
 g_free(s);
diff --git a/migration.c b/migration.c
index da0f192..2f45f66 100644
--- a/migration.c
+++ b/migration.c
@@ -327,8 +327,10 @@ void migrate_fd_put_ready(MigrationState *s)
 int ret;
 static bool first_time = true;

+qemu_mutex_lock_iothread();
 if (s-state != MIG_STATE_ACTIVE) {
 DPRINTF(put_ready returning because of non-active state\n);
+qemu_mutex_unlock_iothread();
 return;
 }
 if (first_time) {
@@ -338,6 +340,7 @@ void migrate_fd_put_ready(MigrationState *s)
 if (ret  0) {
 DPRINTF(failed, %d\n, ret);
 migrate_fd_error(s);
+qemu_mutex_unlock_iothread();
 return;
 }
 }
@@ -374,6 +377,8 @@ void migrate_fd_put_ready(MigrationState *s)
 }
 }
 }
+qemu_mutex_unlock_iothread();
+
 }

 static void migrate_fd_cancel(MigrationState *s)
-- 
1.7.10.4




[Qemu-devel] [PATCH 27/27] buffered_file: unfold buffered_append in buffered_put_buffer

2012-07-24 Thread Juan Quintela
It was the only user, and now buffered_put_buffer just do the append

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |   33 ++---
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index d3bed86..f1a21fa 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -42,22 +42,6 @@ typedef struct QEMUFileBuffered
 do { } while (0)
 #endif

-static void buffered_append(QEMUFileBuffered *s,
-const uint8_t *buf, size_t size)
-{
-if (size  (s-buffer_capacity - s-buffer_size)) {
-DPRINTF(increasing buffer capacity from %zu by %zu\n,
-s-buffer_capacity, size + 1024);
-
-s-buffer_capacity += size + 1024;
-
-s-buffer = g_realloc(s-buffer, s-buffer_capacity);
-}
-
-memcpy(s-buffer + s-buffer_size, buf, size);
-s-buffer_size += size;
-}
-
 static void buffered_flush(QEMUFileBuffered *s)
 {
 size_t offset = 0;
@@ -105,11 +89,22 @@ static int buffered_put_buffer(void *opaque, const uint8_t 
*buf, int64_t pos, in
 return error;
 }

-if (size  0) {
-DPRINTF(buffering %d bytes\n, size - offset);
-buffered_append(s, buf, size);
+if (size = 0) {
+return size;
 }

+if (size  (s-buffer_capacity - s-buffer_size)) {
+DPRINTF(increasing buffer capacity from %zu by %zu\n,
+s-buffer_capacity, size + 1024);
+
+s-buffer_capacity += size + 1024;
+
+s-buffer = g_realloc(s-buffer, s-buffer_capacity);
+}
+
+memcpy(s-buffer + s-buffer_size, buf, size);
+s-buffer_size += size;
+
 return size;
 }

-- 
1.7.10.4




[Qemu-devel] [PATCH 13/22] module additions for schema registration

2012-07-24 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 module.h |2 ++
 vl.c |1 +
 2 files changed, 3 insertions(+)

diff --git a/module.h b/module.h
index c4ccd57..cb81aa2 100644
--- a/module.h
+++ b/module.h
@@ -25,6 +25,7 @@ typedef enum {
 MODULE_INIT_MACHINE,
 MODULE_INIT_QAPI,
 MODULE_INIT_QOM,
+MODULE_INIT_QIDL,
 MODULE_INIT_MAX
 } module_init_type;
 
@@ -32,6 +33,7 @@ typedef enum {
 #define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
 #define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
 #define type_init(function) module_init(function, MODULE_INIT_QOM)
+#define qidl_init(function) module_init(function, MODULE_INIT_QIDL)
 
 void register_module_init(void (*fn)(void), module_init_type type);
 
diff --git a/vl.c b/vl.c
index 8904db1..57ce033 100644
--- a/vl.c
+++ b/vl.c
@@ -2309,6 +2309,7 @@ int main(int argc, char **argv, char **envp)
 }
 
 module_call_init(MODULE_INIT_QOM);
+module_call_init(MODULE_INIT_QIDL);
 
 runstate_init();
 
-- 
1.7.9.5




[Qemu-devel] [PATCH 05/11] Add uleb encoding/decoding functions

2012-07-24 Thread Juan Quintela
From: Orit Wasserman owass...@redhat.com

Implement Unsigned Little Endian Base 128.

Signed-off-by: Orit Wasserman owass...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 cutils.c  |   33 +
 qemu-common.h |8 
 2 files changed, 41 insertions(+)

diff --git a/cutils.c b/cutils.c
index b0bdd4b..700f943 100644
--- a/cutils.c
+++ b/cutils.c
@@ -384,3 +384,36 @@ int64_t pow2floor(int64_t value)
 }
 return value;
 }
+
+/*
+ * Implementation of  ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+int uleb128_encode_small(uint8_t *out, uint32_t n)
+{
+g_assert(n = 0x3fff);
+if (n  0x80) {
+*out++ = n;
+return 1;
+} else {
+*out++ = (n  0x7f) | 0x80;
+*out++ = n  7;
+return 2;
+}
+}
+
+int uleb128_decode_small(const uint8_t *in, uint32_t *n)
+{
+if (!(*in  0x80)) {
+*n = *in++;
+return 1;
+} else {
+*n = *in++  0x7f;
+/* we exceed 14 bit number */
+if (*in  0x80) {
+return -1;
+}
+*n |= *in++  7;
+return 2;
+}
+}
diff --git a/qemu-common.h b/qemu-common.h
index 5ced6ec..6ed48cc 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -425,4 +425,12 @@ int64_t pow2floor(int64_t value);

 #include module.h

+/*
+ * Implementation of ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+ * Input is limited to 14-bit numbers
+ */
+
+int uleb128_encode_small(uint8_t *out, uint32_t n);
+int uleb128_decode_small(const uint8_t *in, uint32_t *n);
+
 #endif
-- 
1.7.10.4




Re: [Qemu-devel] [QEMU RFC PATCH 6/7] i386: topology APIC ID utility functions

2012-07-24 Thread Blue Swirl
On Mon, Jul 23, 2012 at 8:14 PM, Eduardo Habkost ehabk...@redhat.com wrote:
 On Mon, Jul 23, 2012 at 07:44:44PM +, Blue Swirl wrote:
 On Mon, Jul 23, 2012 at 7:28 PM, Eduardo Habkost ehabk...@redhat.com wrote:
  On Mon, Jul 23, 2012 at 07:11:11PM +, Blue Swirl wrote:
  On Mon, Jul 23, 2012 at 6:59 PM, Eduardo Habkost ehabk...@redhat.com 
  wrote:
   On Mon, Jul 23, 2012 at 04:49:07PM +, Blue Swirl wrote:
   On Mon, Jul 16, 2012 at 5:42 PM, Eduardo Habkost ehabk...@redhat.com 
   wrote:
On Sat, Jul 14, 2012 at 09:14:30AM +, Blue Swirl wrote:
[...]
  diff --git a/tests/Makefile b/tests/Makefile
  index b605e14..89bd890 100644
  --- a/tests/Makefile
  +++ b/tests/Makefile
  @@ -15,6 +15,7 @@ check-unit-y += 
  tests/test-string-output-visitor$(EXESUF)
   check-unit-y += tests/test-coroutine$(EXESUF)
   check-unit-y += tests/test-visitor-serialization$(EXESUF)
   check-unit-y += tests/test-iov$(EXESUF)
  +check-unit-y += tests/test-x86-cpuid$(EXESUF)

 This probably tries to build the cpuid test also for non-x86 
 targets
 and break them all.

 I don't think there's any concept of targets for the check-unit 
 tests.
   
How about:
check-qtest-i386-y = tests/test-x86-cpuid$(EXESUF)
   
test-x86-cpuid is not a qtest test case.
  
   Why not? I don't think it is a unit test either, judging from what the
   other unit tests do.
  
   It is absolutely a unit test. I don't know why you don't think so. It
   simply checks the results of the APIC ID calculation functions.
 
  Yes, but the other 'unit tests' (the names used here are very
  confusing, btw) check supporting functions like coroutines, not
  hardware. Hardware tests (qtest) need to bind to an architecture, in
  this case x86.
 
  test-x86-cpuid doesn't check hardware, either. It just checks the simple
  functions that calculate APIC IDs (to make sure the math is correct).
  Those functions aren't even used by any hardware emulation code until
  later in the patch series (when the CPU initialization code gets changed
  to use the new function).

 By that time the function is clearly x86 HW and the check is an x86
 hardware check. QEMU as whole consists of simple functions that
 calculate something.

 It's useful onily for a specific architecture, yes, but it surely
 doesn't make libqtest necessary.

 That's the difference between the unit tests and qtest test cases: unit
 tests simply test small parts of the code (that may or may not be
 hardware-specific), and qtest tests hardware emulation after starting up
 a whole qemu process. It's a different kind of testing, with different
 sets of goals.


Thanks for the clarification. I agree now that this is not a qtest. I
think this is a new category of tests compared to those we have now:
supporting function unit tests and hardware tests at device I/O
boundary level.

 I suppose you are not arguing that no function inside target-* would be
 ever allowed to have a unit test written for it. That would be a very
 silly constraint for people writing tests.

Of course. What I really want is that if x86 targets are not built,
this test is skipped like qtests. This could be achieved with
something like:

check-unit-arch-i386-y = tests/test-x86-cpuid$(EXESUF)
check-unit-y += $(foreach TARGET,$(TARGETS), $(check-unit-arch-$(TARGET)-y))


 --
 Eduardo



[Qemu-devel] [PATCH 03/11] Add XBZRLE documentation

2012-07-24 Thread Juan Quintela
From: Orit Wasserman owass...@redhat.com

Signed-off-by: Orit Wasserman owass...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 docs/xbzrle.txt |  136 +++
 1 file changed, 136 insertions(+)
 create mode 100644 docs/xbzrle.txt

diff --git a/docs/xbzrle.txt b/docs/xbzrle.txt
new file mode 100644
index 000..f70e851
--- /dev/null
+++ b/docs/xbzrle.txt
@@ -0,0 +1,136 @@
+XBZRLE (Xor Based Zero Run Length Encoding)
+===
+
+Using XBZRLE (Xor Based Zero Run Length Encoding) allows for the reduction
+of VM downtime and the total live-migration time of Virtual machines.
+It is particularly useful for virtual machines running memory write intensive
+workloads that are typical of large enterprise applications such as SAP ERP
+Systems, and generally speaking for any application that uses a sparse memory
+update pattern.
+
+Instead of sending the changed guest memory page this solution will send a
+compressed version of the updates, thus reducing the amount of data sent during
+live migration.
+In order to be able to calculate the update, the previous memory pages need to
+be stored on the source. Those pages are stored in a dedicated cache
+(hash table) and are
+accessed by their address.
+The larger the cache size the better the chances are that the page has already
+been stored in the cache.
+A small cache size will result in high cache miss rate.
+Cache size can be changed before and during migration.
+
+Format
+===
+
+The compression format performs a XOR between the previous and current content
+of the page, where zero represents an unchanged value.
+The page data delta is represented by zero and non zero runs.
+A zero run is represented by its length (in bytes).
+A non zero run is represented by its length (in bytes) and the new data.
+The run length is encoded using ULEB128 (http://en.wikipedia.org/wiki/LEB128)
+
+There can be more than one valid encoding, the sender may send a longer 
encoding
+for the benefit of reducing computation cost.
+
+page = zrun nzrun
+   | zrun nzrun page
+
+zrun = length
+
+nzrun = length byte...
+
+length = uleb128 encoded integer
+
+On the sender side XBZRLE is used as a compact delta encoding of page updates,
+retrieving the old page content from the cache (default size of 512 MB). The
+receiving side uses the existing page's content and XBZRLE to decode the new
+page's content.
+
+This work was originally based on research results published
+VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live
+Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth.
+Additionally the delta encoder XBRLE was improved further using the XBZRLE
+instead.
+
+XBZRLE has a sustained bandwidth of 2-2.5 GB/s for typical workloads making it
+ideal for in-line, real-time encoding such as is needed for live-migration.
+
+Example
+old buffer:
+1001 zeros
+05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 68 00 00 6b 00 6d
+3074 zeros
+
+new buffer:
+1001 zeros
+01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 68 00 00 67 00 69
+3074 zeros
+
+encoded buffer:
+
+encoded length 24
+e9 07 0f 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 03 01 67 01 01 69
+
+Migration Capabilities
+==
+In order to use XBZRLE the destination QEMU version should be able to
+decode the new format.
+Adding a new migration capabilities command that will allow external management
+to query for it support.
+A typical use for the destination
+{qemu} info migrate_capabilities
+{qemu} xbzrle, ...
+
+In order to enable capabilities for future live migration,
+a new command migrate_set_parameter is introduced:
+{qemu} migrate_set_parameter xbzrle
+
+Usage
+==
+
+1. Activate xbzrle
+2. Set the XBZRLE cache size - the cache size is in MBytes and should be a
+power of 2. The cache default value is 64MBytes.
+3. start outgoing migration
+
+A typical usage scenario:
+On the incoming QEMU:
+{qemu} migrate_set_parameter xbzrle on
+On the outgoing QEMU:
+{qemu} migrate_set_parameter xbzrle on
+{qemu} migrate_set_cachesize 256m
+{qemu} migrate -d tcp:destination.host:
+{qemu} info migrate
+...
+cache size: 67108864 bytes
+transferred ram-duplicate: A kbytes
+transferred ram-normal: B kbytes
+transferred ram-xbrle: C kbytes
+overflow ram-xbrle: D pages
+cache-miss ram-xbrle: E pages
+
+cache-miss: the number of cache misses to date - high cache-miss rate
+indicates that the cache size is set too low.
+overflow: the number of overflows in the decoding which where the delta could
+not be compressed. This can happen if the changes in the pages are too large
+or there are many short changes; for example, changing every second byte (half 
a
+page).
+
+Testing: Testing indicated that live migration with XBZRLE was completed in 110
+seconds, whereas without it would not be able to complete.
+
+A simple synthetic memory r/w 

[Qemu-devel] [PATCH 20/22] qemu-timer: add visit_type_QEMUTimer

2012-07-24 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile |3 ++-
 qemu-timer.c |   25 +
 qemu-timer.h |4 
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 0711f14..c545ebd 100644
--- a/Makefile
+++ b/Makefile
@@ -157,7 +157,8 @@ qemu-img.o: qemu-img-cmds.h
 
 tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
qemu-timer-common.o main-loop.o notify.o \
-   iohandler.o cutils.o iov.o async.o
+   iohandler.o cutils.o iov.o async.o \
+   $(qapi-obj-y) $(qobject-obj-y)
 tools-obj-$(CONFIG_POSIX) += compatfd.o
 
 qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y)
diff --git a/qemu-timer.c b/qemu-timer.c
index de98977..8a67620 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -30,6 +30,7 @@
 #include hw/hw.h
 
 #include qemu-timer.h
+#include qapi/qapi-visit-core.h
 
 #ifdef _WIN32
 #include mmsystem.h
@@ -61,6 +62,30 @@ struct QEMUTimer {
 int scale;
 };
 
+void visit_type_QEMUTimer(Visitor *v, QEMUTimer **obj, const char *name,
+  Error **errp)
+{
+int64_t expire_time, expire_time_cpy;
+if (!obj || !*obj) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : NULL,
+  non-NULL QEMUTimer);
+return;
+}
+expire_time = expire_time_cpy = qemu_timer_expire_time_ns(*obj);
+visit_start_struct(v, NULL, QEMUTimer, name, 0, errp);
+visit_type_int64(v, expire_time, expire_time, errp);
+visit_end_struct(v, errp);
+
+/* if we're modifying a QEMUTimer, re-arm/delete accordingly */
+if (expire_time != expire_time_cpy) {
+if (expire_time != -1) {
+qemu_mod_timer_ns(*obj, expire_time);
+} else {
+qemu_del_timer(*obj);
+}
+}
+}
+
 struct qemu_alarm_timer {
 char const *name;
 int (*start)(struct qemu_alarm_timer *t);
diff --git a/qemu-timer.h b/qemu-timer.h
index f8af595..1feabd7 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -4,6 +4,7 @@
 #include qemu-common.h
 #include main-loop.h
 #include notify.h
+#include qapi/qapi-visit-core.h
 
 #ifdef __FreeBSD__
 #include sys/param.h
@@ -67,6 +68,9 @@ int64_t cpu_get_ticks(void);
 void cpu_enable_ticks(void);
 void cpu_disable_ticks(void);
 
+void visit_type_QEMUTimer(Visitor *v, QEMUTimer **obj, const char *name,
+  Error **errp);
+
 static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
void *opaque)
 {
-- 
1.7.9.5




[Qemu-devel] [PATCH 01/27] buffered_file: g_realloc() can't fail

2012-07-24 Thread Juan Quintela
Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |   10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index f170aa0..4148abb 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -50,20 +50,12 @@ static void buffered_append(QEMUFileBuffered *s,
 const uint8_t *buf, size_t size)
 {
 if (size  (s-buffer_capacity - s-buffer_size)) {
-void *tmp;
-
 DPRINTF(increasing buffer capacity from %zu by %zu\n,
 s-buffer_capacity, size + 1024);

 s-buffer_capacity += size + 1024;

-tmp = g_realloc(s-buffer, s-buffer_capacity);
-if (tmp == NULL) {
-fprintf(stderr, qemu file buffer expansion failed\n);
-exit(1);
-}
-
-s-buffer = tmp;
+s-buffer = g_realloc(s-buffer, s-buffer_capacity);
 }

 memcpy(s-buffer + s-buffer_size, buf, size);
-- 
1.7.10.4




[Qemu-devel] [PATCH 26/27] buffered_file: don't flush on put buffer

2012-07-24 Thread Juan Quintela
We call buffered_put_buffer with iothread held, and buffered_flush() does
synchronous writes.  We only want to do the synchronous writes outside.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |2 --
 1 file changed, 2 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index ac2327b..d3bed86 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -110,8 +110,6 @@ static int buffered_put_buffer(void *opaque, const uint8_t 
*buf, int64_t pos, in
 buffered_append(s, buf, size);
 }

-buffered_flush(s);
-
 return size;
 }

-- 
1.7.10.4




[Qemu-devel] [PATCH 22/27] migration: make writes blocking

2012-07-24 Thread Juan Quintela
Move all the writes to the migration_thread, and make writings
blocking.  Notice that are still using the iothread for everything
that we do.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 migration-exec.c |2 --
 migration-fd.c   |6 --
 migration-tcp.c  |2 +-
 migration-unix.c |2 --
 migration.c  |   18 --
 qemu-file.h  |5 -
 savevm.c |5 -
 7 files changed, 1 insertion(+), 39 deletions(-)

diff --git a/migration-exec.c b/migration-exec.c
index 6c97db9..908f22e 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -76,8 +76,6 @@ int exec_start_outgoing_migration(MigrationState *s, const 
char *command)
 goto err_after_open;
 }

-socket_set_nonblock(s-fd);
-
 s-opaque = qemu_popen(f, w);

 s-close = exec_close;
diff --git a/migration-fd.c b/migration-fd.c
index 50138ed..e5be972 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -81,11 +81,6 @@ int fd_start_outgoing_migration(MigrationState *s, const 
char *fdname)
 goto err_after_get_fd;
 }

-if (fcntl(s-fd, F_SETFL, O_NONBLOCK) == -1) {
-DPRINTF(Unable to set nonblocking mode on file descriptor\n);
-goto err_after_open;
-}
-
 s-get_error = fd_errno;
 s-write = fd_write;
 s-close = fd_close;
@@ -93,7 +88,6 @@ int fd_start_outgoing_migration(MigrationState *s, const char 
*fdname)
 migrate_fd_connect(s);
 return 0;

-err_after_open:
 close(s-fd);
 err_after_get_fd:
 return -1;
diff --git a/migration-tcp.c b/migration-tcp.c
index 440804d..d2bfb03 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -86,7 +86,7 @@ int tcp_start_outgoing_migration(MigrationState *s, const 
char *host_port,
 s-write = socket_write;
 s-close = tcp_close;

-s-fd = inet_connect(host_port, false, errp);
+s-fd = inet_connect(host_port, true, errp);

 if (!error_is_set(errp)) {
 migrate_fd_connect(s);
diff --git a/migration-unix.c b/migration-unix.c
index 169de88..bb41bac 100644
--- a/migration-unix.c
+++ b/migration-unix.c
@@ -96,8 +96,6 @@ int unix_start_outgoing_migration(MigrationState *s, const 
char *path)
 return -errno;
 }

-socket_set_nonblock(s-fd);
-
 do {
 ret = connect(s-fd, (struct sockaddr *)addr, sizeof(addr));
 if (ret == -1) {
diff --git a/migration.c b/migration.c
index e3eec97..fe2afd0 100644
--- a/migration.c
+++ b/migration.c
@@ -257,8 +257,6 @@ static int migrate_fd_cleanup(MigrationState *s)
 {
 int ret = 0;

-qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL);
-
 if (s-file) {
 DPRINTF(closing file\n);
 ret = qemu_fclose(s-file);
@@ -293,17 +291,6 @@ static void migrate_fd_completed(MigrationState *s)
 notifier_list_notify(migration_state_notifiers, s);
 }

-static void migrate_fd_put_notify(void *opaque)
-{
-MigrationState *s = opaque;
-
-qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL);
-qemu_file_put_notify(s-file);
-if (s-file  qemu_file_get_error(s-file)) {
-migrate_fd_error(s);
-}
-}
-
 ssize_t migrate_fd_put_buffer(MigrationState *s, const void *data,
   size_t size)
 {
@@ -320,10 +307,6 @@ ssize_t migrate_fd_put_buffer(MigrationState *s, const 
void *data,
 if (ret == -1)
 ret = -(s-get_error(s));

-if (ret == -EAGAIN) {
-qemu_set_fd_handler2(s-fd, NULL, NULL, migrate_fd_put_notify, s);
-}
-
 return ret;
 }

@@ -431,7 +414,6 @@ void migrate_fd_wait_for_unfreeze(MigrationState *s)

 int migrate_fd_close(MigrationState *s)
 {
-qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL);
 return s-close(s);
 }

diff --git a/qemu-file.h b/qemu-file.h
index 31b83f6..af7c36f 100644
--- a/qemu-file.h
+++ b/qemu-file.h
@@ -106,11 +106,6 @@ int64_t qemu_file_get_rate_limit(QEMUFile *f);
 int qemu_file_get_error(QEMUFile *f);
 void qemu_file_set_error(QEMUFile *f, int error);

-/* Try to send any outstanding data.  This function is useful when output is
- * halted due to rate limiting or EAGAIN errors occur as it can be used to
- * resume output. */
-void qemu_file_put_notify(QEMUFile *f);
-
 static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
 {
 qemu_put_be64(f, *pv);
diff --git a/savevm.c b/savevm.c
index c5fd13f..2c34faa 100644
--- a/savevm.c
+++ b/savevm.c
@@ -546,11 +546,6 @@ int qemu_fclose(QEMUFile *f)
 return ret;
 }

-void qemu_file_put_notify(QEMUFile *f)
-{
-f-put_buffer(f-opaque, NULL, 0, 0);
-}
-
 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
 {
 int l;
-- 
1.7.10.4




[Qemu-devel] [PATCH 09/27] ram: introduce migration_bitmap_sync()

2012-07-24 Thread Juan Quintela
Helper that we use each time that we need to syncronize the migration
bitmap with the other dirty bitmaps.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |   10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index c49c321..d21b2a3 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -367,6 +367,12 @@ static inline void migration_bitmap_set_dirty(MemoryRegion 
*mr, int length)
 }
 }

+static void migration_bitmap_sync(void)
+{
+memory_global_sync_dirty_bitmap(get_system_memory());
+}
+
+
 /*
  * ram_save_block: Writes a page of memory to the stream f
  *
@@ -631,7 +637,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 expected_time, migrate_max_downtime());

 if (expected_time = migrate_max_downtime()) {
-memory_global_sync_dirty_bitmap(get_system_memory());
+migration_bitmap_sync();
 expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;

 return expected_time = migrate_max_downtime();
@@ -641,7 +647,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)

 static int ram_save_complete(QEMUFile *f, void *opaque)
 {
-memory_global_sync_dirty_bitmap(get_system_memory());
+migration_bitmap_sync();

 qemu_mutex_lock_ramlist();

-- 
1.7.10.4




[Qemu-devel] [PATCH 06/22] qapi: add visitor interfaces for arrays

2012-07-24 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 qapi/qapi-visit-core.c |   25 +
 qapi/qapi-visit-core.h |8 
 scripts/qapi_visit.py  |   28 
 3 files changed, 61 insertions(+)

diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 7a82b63..631387d 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -311,3 +311,28 @@ void input_type_enum(Visitor *v, int *obj, const char 
*strings[],
 g_free(enum_str);
 *obj = value;
 }
+
+void visit_start_array(Visitor *v, void **obj, const char *name,
+   size_t elem_count, size_t elem_size, Error **errp)
+{
+g_assert(v-start_array);
+if (!error_is_set(errp)) {
+v-start_array(v, obj, name, elem_count, elem_size, errp);
+}
+}
+
+void visit_next_array(Visitor *v, Error **errp)
+{
+g_assert(v-next_array);
+if (!error_is_set(errp)) {
+v-next_array(v, errp);
+}
+}
+
+void visit_end_array(Visitor *v, Error **errp)
+{
+g_assert(v-end_array);
+if (!error_is_set(errp)) {
+v-end_array(v, errp);
+}
+}
diff --git a/qapi/qapi-visit-core.h b/qapi/qapi-visit-core.h
index 60aceda..4a7bdb6 100644
--- a/qapi/qapi-visit-core.h
+++ b/qapi/qapi-visit-core.h
@@ -43,6 +43,10 @@ struct Visitor
 void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
 void (*type_number)(Visitor *v, double *obj, const char *name,
 Error **errp);
+void (*start_array)(Visitor *v, void **obj, const char *name,
+size_t elem_count, size_t elem_size, Error **errp);
+void (*next_array)(Visitor *v, Error **errp);
+void (*end_array)(Visitor *v, Error **errp);
 
 /* May be NULL */
 void (*start_optional)(Visitor *v, bool *present, const char *name,
@@ -91,5 +95,9 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char 
*name, Error **errp);
 void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
 void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
 void visit_type_number(Visitor *v, double *obj, const char *name, Error 
**errp);
+void visit_start_array(Visitor *v, void **obj, const char *name,
+   size_t elem_count, size_t elem_size, Error **errp);
+void visit_next_array(Visitor *v, Error **errp);
+void visit_end_array(Visitor *v, Error **errp);
 
 #endif
diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
index 9839e3c..bf93bfe 100644
--- a/scripts/qapi_visit.py
+++ b/scripts/qapi_visit.py
@@ -33,6 +33,34 @@ visit_end_array(m, errp);
 count=info['array_size'])
 return ret
 
+def generate_visit_array_body(name, info):
+if info['array_size'][0].isdigit():
+array_size = info['array_size']
+elif info['array_size'][0] == '(' and info['array_size'][-1] == ')':
+array_size = info['array_size']
+else:
+array_size = (*obj)-%s % info['array_size']
+
+if info.has_key('array_capacity'):
+array_capacity = info['array_capacity']
+else:
+array_capacity = array_size
+
+ret = mcgen('''
+visit_start_array(m, (void **)obj, %(name)s, %(array_capacity)s, 
sizeof(%(type)s), errp);
+int %(name)s_i;
+for (%(name)s_i = 0; %(name)s_i  %(array_size)s; %(name)s_i++) {
+visit_type_%(type_short)s(m, (*obj)-%(name)s[%(name)s_i], NULL, errp);
+visit_next_array(m, errp);
+}
+visit_end_array(m, errp);
+''',
+name=name, type=c_type(info['type'][0]),
+type_short=info['type'][0],
+array_size=array_size,
+array_capacity=array_capacity)
+return ret
+
 def generate_visit_struct_body(field_prefix, name, members):
 ret = mcgen('''
 if (!error_is_set(errp)) {
-- 
1.7.9.5




[Qemu-devel] [PATCH 07/27] ram: Introduce migration_bitmap_test_and_reset_dirty()

2012-07-24 Thread Juan Quintela
It just test if the dirty bit is set, and clears it.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |   19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index b47bf05..c49c321 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -342,6 +342,19 @@ static RAMBlock *last_block;
 static ram_addr_t last_offset;
 static uint32_t last_version;

+static inline bool migration_bitmap_test_and_reset_dirty(MemoryRegion *mr,
+ ram_addr_t offset)
+{
+bool ret = memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE,
+   DIRTY_MEMORY_MIGRATION);
+
+if (ret) {
+memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE,
+  DIRTY_MEMORY_MIGRATION);
+}
+return ret;
+}
+
 static inline void migration_bitmap_set_dirty(MemoryRegion *mr, int length)
 {
 ram_addr_t addr;
@@ -375,14 +388,10 @@ static int ram_save_block(QEMUFile *f, bool last_stage)

 do {
 mr = block-mr;
-if (memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE,
-DIRTY_MEMORY_MIGRATION)) {
+if (migration_bitmap_test_and_reset_dirty(mr, offset)) {
 uint8_t *p;
 int cont = (block == last_block) ? RAM_SAVE_FLAG_CONTINUE : 0;

-memory_region_reset_dirty(mr, offset, TARGET_PAGE_SIZE,
-  DIRTY_MEMORY_MIGRATION);
-
 p = memory_region_get_ram_ptr(mr) + offset;

 if (is_dup_page(p)) {
-- 
1.7.10.4




[Qemu-devel] [PATCH 17/27] buffered_file: unfold migrate_fd_put_buffer

2012-07-24 Thread Juan Quintela
We only used it once, just remove the callback indirection.

Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |7 ++-
 buffered_file.h |5 +
 migration.c |8 ++--
 migration.h |1 +
 4 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index d257496..4fca774 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -23,7 +23,6 @@

 typedef struct QEMUFileBuffered
 {
-BufferedCloseFunc *close;
 MigrationState *migration_state;
 QEMUFile *file;
 int freeze_output;
@@ -147,7 +146,7 @@ static int buffered_close(void *opaque)
 migrate_fd_wait_for_unfreeze(s-migration_state);
 }

-ret = s-close(s-migration_state);
+ret = migrate_fd_close(s-migration_state);

 qemu_del_timer(s-timer);
 qemu_free_timer(s-timer);
@@ -224,8 +223,7 @@ static void buffered_rate_tick(void *opaque)
 }

 QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
-  size_t bytes_per_sec,
-  BufferedCloseFunc *close)
+  size_t bytes_per_sec)
 {
 QEMUFileBuffered *s;

@@ -233,7 +231,6 @@ QEMUFile *qemu_fopen_ops_buffered(MigrationState 
*migration_state,

 s-migration_state = migration_state;
 s-xfer_limit = bytes_per_sec / 10;
-s-close = close;

 s-file = qemu_fopen_ops(s, buffered_put_buffer, NULL,
  buffered_close, buffered_rate_limit,
diff --git a/buffered_file.h b/buffered_file.h
index 926e5c6..8a38754 100644
--- a/buffered_file.h
+++ b/buffered_file.h
@@ -17,10 +17,7 @@
 #include hw/hw.h
 #include migration.h

-typedef int (BufferedCloseFunc)(void *opaque);
-
 QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state,
-  size_t xfer_limit,
-  BufferedCloseFunc *close);
+  size_t xfer_limit);

 #endif
diff --git a/migration.c b/migration.c
index 3561b16..c639c99 100644
--- a/migration.c
+++ b/migration.c
@@ -396,10 +396,8 @@ void migrate_fd_wait_for_unfreeze(MigrationState *s)
 }
 }

-static int migrate_fd_close(void *opaque)
+int migrate_fd_close(MigrationState *s)
 {
-MigrationState *s = opaque;
-
 qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL);
 return s-close(s);
 }
@@ -435,9 +433,7 @@ void migrate_fd_connect(MigrationState *s)
 int ret;

 s-state = MIG_STATE_ACTIVE;
-s-file = qemu_fopen_ops_buffered(s,
-  s-bandwidth_limit,
-  migrate_fd_close);
+s-file = qemu_fopen_ops_buffered(s, s-bandwidth_limit);

 DPRINTF(beginning savevm\n);
 ret = qemu_savevm_state_begin(s-file, s-params);
diff --git a/migration.h b/migration.h
index 62fc4f3..f3a684a 100644
--- a/migration.h
+++ b/migration.h
@@ -79,6 +79,7 @@ ssize_t migrate_fd_put_buffer(MigrationState *s, const void 
*data,
   size_t size);
 void migrate_fd_put_ready(MigrationState *s);
 void migrate_fd_wait_for_unfreeze(MigrationState *s);
+int migrate_fd_close(MigrationState *s);

 void add_migration_state_change_notifier(Notifier *notify);
 void remove_migration_state_change_notifier(Notifier *notify);
-- 
1.7.10.4




[Qemu-devel] [PATCH 12/27] buffered_file: rename opaque to migration_state

2012-07-24 Thread Juan Quintela
Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |   12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index 7155800..33b700b 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -27,7 +27,7 @@ typedef struct QEMUFileBuffered
 BufferedPutReadyFunc *put_ready;
 BufferedWaitForUnfreezeFunc *wait_for_unfreeze;
 BufferedCloseFunc *close;
-void *opaque;
+void *migration_state;
 QEMUFile *file;
 int freeze_output;
 size_t bytes_xfer;
@@ -78,7 +78,7 @@ static void buffered_flush(QEMUFileBuffered *s)
 while (s-bytes_xfer  s-xfer_limit  offset  s-buffer_size) {
 ssize_t ret;

-ret = s-put_buffer(s-opaque, s-buffer + offset,
+ret = s-put_buffer(s-migration_state, s-buffer + offset,
 s-buffer_size - offset);
 if (ret == -EAGAIN) {
 DPRINTF(backend not ready, freezing\n);
@@ -129,7 +129,7 @@ static int buffered_put_buffer(void *opaque, const uint8_t 
*buf, int64_t pos, in
 DPRINTF(file is ready\n);
 if (!s-freeze_output  s-bytes_xfer  s-xfer_limit) {
 DPRINTF(notifying client\n);
-s-put_ready(s-opaque);
+s-put_ready(s-migration_state);
 }
 }

@@ -147,10 +147,10 @@ static int buffered_close(void *opaque)
 while (!qemu_file_get_error(s-file)  s-buffer_size) {
 buffered_flush(s);
 if (s-freeze_output)
-s-wait_for_unfreeze(s-opaque);
+s-wait_for_unfreeze(s-migration_state);
 }

-ret = s-close(s-opaque);
+ret = s-close(s-migration_state);

 qemu_del_timer(s-timer);
 qemu_free_timer(s-timer);
@@ -237,7 +237,7 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque,

 s = g_malloc0(sizeof(*s));

-s-opaque = opaque;
+s-migration_state = opaque;
 s-xfer_limit = bytes_per_sec / 10;
 s-put_buffer = put_buffer;
 s-put_ready = put_ready;
-- 
1.7.10.4




[Qemu-devel] [RFC 00/27] Migration thread (WIP)

2012-07-24 Thread Juan Quintela
Hi

This series are on top of the migration-next-v5 series just posted.

First of all, this is an RFC/Work in progress.  Just a lot of people
asked for it, and I would like review of the design.

It does:
- get a new bitmap for migration, and that bitmap uses 1 bit by page
- it unfolds migration_buffered_file.  Only one user existed.
- it simplifies buffered_file a lot.

- About the migration thread, special attention was giving to try to
  get the series review-able (reviewers would tell if I got it).

Basic design:
- we create a new thread instead of a timer function
- we move all the migration work to that thread (but run everything
  except the waits with the iothread lock.
- we move all the writting to outside the iothread lock.  i.e.
  we walk the state with the iothread hold, and copy everything to one buffer.
  then we write that buffer to the sockets outside the iothread lock.
- once here, we move to writting synchronously to the sockets.
- this allows us to simplify quite a lot.

And basically, that is it.  Notice that we still do the iterate page
walking with the iothread held.  Light testing show that we got
similar speed and latencies than without the thread (notice that
almost no optimizations done here yet).

Appart of the review:
- Are there any locking issues that I have missed (I guess so)
- stop all cpus correctly.  vm_stop should be called from the iothread,
  I use the trick of using a bottom half to get that working correctly.
  but this _implementation_ is ugly as hell.  Is there an easy way
  of doing it?
- Do I really have to export last_ram_offset(), there is no other way
  of knowing the ammount of RAM?

Known issues:

- for some reason, when it has to start a 2nd round of bitmap
  handling, it decides to dirty all pages.  Haven't found still why
  this happens.

If you can test it, and said me where it breaks, it would also help.

Work is based on Umesh thread work, and work that Paolo Bonzini had
work on top of that.  All the mirgation thread was done from scratch
becase I was unable to debug why it was failing, but it owes a lot
to the previous design.

Thanks in advance, Juan.

The following changes since commit a21143486b9c6d7a50b7b62877c02b3c686943cb:

  Merge remote-tracking branch 'stefanha/net' into staging (2012-07-23 13:15:34 
-0500)

are available in the git repository at:


  http://repo.or.cz/r/qemu/quintela.git migration-thread-v1

for you to fetch changes up to 27e539b03ba97bc37e107755bcb44511ec4c8100:

  buffered_file: unfold buffered_append in buffered_put_buffer (2012-07-24 
16:46:13 +0200)


Juan Quintela (23):
  buffered_file: g_realloc() can't fail
  savevm: Factorize ram globals reset in its own function
  ram: introduce migration_bitmap_set_dirty()
  ram: Introduce migration_bitmap_test_and_reset_dirty()
  ram: Export last_ram_offset()
  ram: introduce migration_bitmap_sync()
  Separate migration bitmap
  buffered_file: rename opaque to migration_state
  buffered_file: opaque is MigrationState
  buffered_file: unfold migrate_fd_put_buffer
  buffered_file: unfold migrate_fd_put_ready
  buffered_file: unfold migrate_fd_put_buffer
  buffered_file: unfold migrate_fd_put_buffer
  buffered_file: We can access directly to bandwidth_limit
  buffered_file: Move from using a timer to use a thread
  migration: make qemu_fopen_ops_buffered() return void
  migration: stop all cpus correctly
  migration: make writes blocking
  migration: remove unfreeze logic
  migration: take finer locking
  buffered_file: Unfold the trick to restart generating migration data
  buffered_file: don't flush on put buffer
  buffered_file: unfold buffered_append in buffered_put_buffer

Paolo Bonzini (2):
  split MRU ram list
  BufferedFile: append, then flush

Umesh Deshpande (2):
  add a version number to ram_list
  protect the ramlist with a separate mutex

 arch_init.c  |  108 +---
 buffered_file.c  |  179 +-
 buffered_file.h  |   12 +---
 cpu-all.h|   17 +-
 exec-obsolete.h  |   10 ---
 exec.c   |   45 +++---
 migration-exec.c |2 -
 migration-fd.c   |6 --
 migration-tcp.c  |2 +-
 migration-unix.c |2 -
 migration.c  |  111 ++---
 migration.h  |6 ++
 qemu-file.h  |5 --
 savevm.c |5 --
 14 files changed, 249 insertions(+), 261 deletions(-)

-- 
1.7.10.4




[Qemu-devel] [PATCH 04/27] add a version number to ram_list

2012-07-24 Thread Juan Quintela
From: Umesh Deshpande udesh...@redhat.com

This will be used to detect if last_block might have become invalid
across different calls to ram_save_live.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Umesh Deshpande udesh...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 arch_init.c |6 ++
 cpu-all.h   |1 +
 exec.c  |4 
 3 files changed, 11 insertions(+)

diff --git a/arch_init.c b/arch_init.c
index 02d36ce..9e05aae 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -340,6 +340,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
*current_data,

 static RAMBlock *last_block;
 static ram_addr_t last_offset;
+static uint32_t last_version;

 /*
  * ram_save_block: Writes a page of memory to the stream f
@@ -496,6 +497,7 @@ static void reset_ram_globals(void)
 {
 last_block = NULL;
 last_offset = 0;
+last_version = ram_list.version;
 sort_ram_list();
 }

@@ -554,6 +556,10 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 int i;
 uint64_t expected_time;

+if (ram_list.version != last_version) {
+reset_ram_globals();
+}
+
 bytes_transferred_last = bytes_transferred;
 bwidth = qemu_get_clock_ns(rt_clock);

diff --git a/cpu-all.h b/cpu-all.h
index ca3bb24..429b2c6 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -486,6 +486,7 @@ typedef struct RAMBlock {

 typedef struct RAMList {
 uint8_t *phys_dirty;
+uint32_t version;
 QLIST_HEAD(, RAMBlock) blocks_mru;
 QLIST_HEAD(, RAMBlock) blocks;
 uint64_t dirty_pages;
diff --git a/exec.c b/exec.c
index afc472f..ceffa4f 100644
--- a/exec.c
+++ b/exec.c
@@ -2555,6 +2555,8 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void 
*host,
 QLIST_INSERT_HEAD(ram_list.blocks, new_block, next);
 QLIST_INSERT_HEAD(ram_list.blocks_mru, new_block, next_mru);

+ram_list.version++;
+
 ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
last_ram_offset()  TARGET_PAGE_BITS);
 cpu_physical_memory_set_dirty_range(new_block-offset, size, 0xff);
@@ -2578,6 +2580,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr)
 if (addr == block-offset) {
 QLIST_REMOVE(block, next);
 QLIST_REMOVE(block, next_mru);
+ram_list.version++;
 g_free(block);
 return;
 }
@@ -2592,6 +2595,7 @@ void qemu_ram_free(ram_addr_t addr)
 if (addr == block-offset) {
 QLIST_REMOVE(block, next);
 QLIST_REMOVE(block, next_mru);
+ram_list.version++;
 if (block-flags  RAM_PREALLOC_MASK) {
 ;
 } else if (mem_path) {
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH 7/7] s390: make sclp ascii console the default

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 7:37 AM, Christian Borntraeger
borntrae...@de.ibm.com wrote:
 This patch makes the sclp ascii default for S390.

 Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
 ---
  hw/s390-virtio.c |1 -
  vl.c |   44 
  2 files changed, 44 insertions(+), 1 deletions(-)

 diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
 index 28e320d..8b48f66 100644
 --- a/hw/s390-virtio.c
 +++ b/hw/s390-virtio.c
 @@ -341,7 +341,6 @@ static QEMUMachine s390_machine = {
  .no_serial = 1,
  .no_parallel = 1,
  .no_sdcard = 1,
 -.use_virtcon = 1,
  .max_cpus = 255,
  .is_default = 1,
  };
 diff --git a/vl.c b/vl.c
 index 46248b9..7197724 100644
 --- a/vl.c
 +++ b/vl.c
 @@ -168,6 +168,7 @@ int main(int argc, char **argv)
  #define DEFAULT_RAM_SIZE 128

  #define MAX_VIRTIO_CONSOLES 1
 +#define MAX_SCLP_CONSOLES   1

  static const char *data_dir;
  const char *bios_name = NULL;
 @@ -195,6 +196,7 @@ int no_quit = 0;
  CharDriverState *serial_hds[MAX_SERIAL_PORTS];
  CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
  CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
 +CharDriverState *sclpcon_hds[MAX_SCLP_CONSOLES];
  int win2k_install_hack = 0;
  int usb_enabled = 0;
  int singlestep = 0;
 @@ -268,6 +270,7 @@ static int default_floppy = 1;
  static int default_cdrom = 1;
  static int default_sdcard = 1;
  static int default_vga = 1;
 +static int default_sclpcon = 1;

  static struct {
  const char *driver;
 @@ -289,6 +292,7 @@ static struct {
  { .driver = isa-cirrus-vga,   .flag = default_vga   },
  { .driver = vmware-svga,  .flag = default_vga   },
  { .driver = qxl-vga,  .flag = default_vga   },
 +{ .driver = sclpconsole,  .flag = default_sclpcon   },
  };

  static void res_free(void)
 @@ -1935,6 +1939,7 @@ struct device_config {
  DEV_VIRTCON,   /* -virtioconsole */
  DEV_DEBUGCON,  /* -debugcon */
  DEV_GDB,   /* -gdb, -s */
 +DEV_SCLPCON,   /* sclp console */
  } type;
  const char *cmdline;
  Location loc;
 @@ -2014,6 +2019,36 @@ static int parallel_parse(const char *devname)
  return 0;
  }

 +static int sclpcon_parse(const char *devname)
 +{
 +QemuOptsList *device = qemu_find_opts(device);
 +static int index = 0;
 +char label[32];
 +QemuOpts *dev_opts;
 +
 +if (strcmp(devname, none) == 0)

Braces.

 +return 0;
 +if (index == MAX_SCLP_CONSOLES) {
 +fprintf(stderr, qemu: too many sclp consoles\n);

The user may wonder what is the max, you could tell that.

 +exit(1);
 +}
 +
 +dev_opts = qemu_opts_create(device, NULL, 0, NULL);
 +qemu_opt_set(dev_opts, driver, sclpconsole);
 +
 +snprintf(label, sizeof(label), sclpcon%d, index);
 +sclpcon_hds[index] = qemu_chr_new(label, devname, NULL);
 +if (!sclpcon_hds[index]) {
 +fprintf(stderr, qemu: could not open sclp console '%s': %s\n,
 +devname, strerror(errno));
 +return -1;
 +}
 +qemu_opt_set(dev_opts, chardev, label);
 +
 +index++;
 +return 0;
 +}
 +
  static int virtcon_parse(const char *devname)
  {
  QemuOptsList *device = qemu_find_opts(device);
 @@ -3122,6 +3157,7 @@ int main(int argc, char **argv, char **envp)
  default_cdrom = 0;
  default_sdcard = 0;
  default_vga = 0;
 +default_sclpcon = 0;
  break;
  case QEMU_OPTION_xen_domid:
  if (!(xen_available())) {
 @@ -3303,11 +3339,15 @@ int main(int argc, char **argv, char **envp)
  add_device_config(DEV_PARALLEL, null);
  if (default_serial  default_monitor) {
  add_device_config(DEV_SERIAL, mon:stdio);
 +} else if (default_sclpcon  default_monitor) {
 +add_device_config(DEV_SCLPCON, mon:stdio);
  } else if (default_virtcon  default_monitor) {
  add_device_config(DEV_VIRTCON, mon:stdio);
  } else {
  if (default_serial)
  add_device_config(DEV_SERIAL, stdio);
 +if (default_sclpcon)

Braces, also below two times.

 +add_device_config(DEV_SCLPCON, stdio);
  if (default_virtcon)
  add_device_config(DEV_VIRTCON, stdio);
  if (default_monitor)
 @@ -3320,6 +3360,8 @@ int main(int argc, char **argv, char **envp)
  add_device_config(DEV_PARALLEL, vc:80Cx24C);
  if (default_monitor)
  monitor_parse(vc:80Cx24C, readline);
 +if (default_sclpcon)
 +add_device_config(DEV_SCLPCON, vc:80Cx24C);
  if (default_virtcon)
  add_device_config(DEV_VIRTCON, vc:80Cx24C);
  }
 @@ -3490,6 +3532,8 @@ int main(int argc, char **argv, char **envp)
  exit(1);
  if (foreach_device_config(DEV_PARALLEL, parallel_parse)  0)
  exit(1);
 +  

[Qemu-devel] [PATCH 11/27] BufferedFile: append, then flush

2012-07-24 Thread Juan Quintela
From: Paolo Bonzini pbonz...@redhat.com

Simplify the logic for pushing data from the buffer to the output
pipe/socket.  This also matches more closely what will be the
operation of the migration thread.

Signed-off-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Juan Quintela quint...@redhat.com
---
 buffered_file.c |   50 +++---
 1 file changed, 11 insertions(+), 39 deletions(-)

diff --git a/buffered_file.c b/buffered_file.c
index 4148abb..7155800 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -75,7 +75,7 @@ static void buffered_flush(QEMUFileBuffered *s)

 DPRINTF(flushing %zu byte(s) of data\n, s-buffer_size);

-while (offset  s-buffer_size) {
+while (s-bytes_xfer  s-xfer_limit  offset  s-buffer_size) {
 ssize_t ret;

 ret = s-put_buffer(s-opaque, s-buffer + offset,
@@ -93,6 +93,7 @@ static void buffered_flush(QEMUFileBuffered *s)
 } else {
 DPRINTF(flushed %zd byte(s)\n, ret);
 offset += ret;
+s-bytes_xfer += ret;
 }
 }

@@ -104,8 +105,7 @@ static void buffered_flush(QEMUFileBuffered *s)
 static int buffered_put_buffer(void *opaque, const uint8_t *buf, int64_t pos, 
int size)
 {
 QEMUFileBuffered *s = opaque;
-int offset = 0, error;
-ssize_t ret;
+int error;

 DPRINTF(putting %d bytes at % PRId64 \n, size, pos);

@@ -118,48 +118,22 @@ static int buffered_put_buffer(void *opaque, const 
uint8_t *buf, int64_t pos, in
 DPRINTF(unfreezing output\n);
 s-freeze_output = 0;

-buffered_flush(s);
-
-while (!s-freeze_output  offset  size) {
-if (s-bytes_xfer  s-xfer_limit) {
-DPRINTF(transfer limit exceeded when putting\n);
-break;
-}
-
-ret = s-put_buffer(s-opaque, buf + offset, size - offset);
-if (ret == -EAGAIN) {
-DPRINTF(backend not ready, freezing\n);
-s-freeze_output = 1;
-break;
-}
-
-if (ret = 0) {
-DPRINTF(error putting\n);
-qemu_file_set_error(s-file, ret);
-offset = -EINVAL;
-break;
-}
-
-DPRINTF(put %zd byte(s)\n, ret);
-offset += ret;
-s-bytes_xfer += ret;
-}
-
-if (offset = 0) {
+if (size  0) {
 DPRINTF(buffering %d bytes\n, size - offset);
-buffered_append(s, buf + offset, size - offset);
-offset = size;
+buffered_append(s, buf, size);
 }

+buffered_flush(s);
+
 if (pos == 0  size == 0) {
 DPRINTF(file is ready\n);
-if (s-bytes_xfer = s-xfer_limit) {
+if (!s-freeze_output  s-bytes_xfer  s-xfer_limit) {
 DPRINTF(notifying client\n);
 s-put_ready(s-opaque);
 }
 }

-return offset;
+return size;
 }

 static int buffered_close(void *opaque)
@@ -169,6 +143,7 @@ static int buffered_close(void *opaque)

 DPRINTF(closing\n);

+s-xfer_limit = INT_MAX;
 while (!qemu_file_get_error(s-file)  s-buffer_size) {
 buffered_flush(s);
 if (s-freeze_output)
@@ -248,10 +223,7 @@ static void buffered_rate_tick(void *opaque)

 s-bytes_xfer = 0;

-buffered_flush(s);
-
-/* Add some checks around this */
-s-put_ready(s-opaque);
+buffered_put_buffer(s, NULL, 0, 0);
 }

 QEMUFile *qemu_fopen_ops_buffered(void *opaque,
-- 
1.7.10.4




Re: [Qemu-devel] [PATCH 6/7] s390: sclp ascii console support

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 7:37 AM, Christian Borntraeger
borntrae...@de.ibm.com wrote:
 From: Heinz Graalfs graa...@linux.vnet.ibm.com

 This code adds console support  by implementing SCLP's ASCII Console
 Data event. This is the same console as LPARs ASCII console or z/VMs
 sysascii.

 The console can be specified manually with something like
 -chardev stdio,id=charconsole0 -device 
 sclpconsole,chardev=charconsole0,id=console0

 Newer kernels will autodetect that console and prefer that over virtio
 console.

 When data is received from the character layer it creates a service
 interrupt to trigger a Read Event Data command from the guest that will
 pick up the received character byte-stream.
 When characters are echo'ed by the linux guest a Write Event Data occurs
 which is forwarded by the Event Facility to the console that supports
 a corresponding mask value.
 Console resizing is not supported.
 The character layer byte-stream is buffered using a fixed size iov
 buffer.

 Signed-off-by: Heinz Graalfs graa...@linux.vnet.ibm.com
 Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
 ---
  hw/s390x/Makefile.objs |2 +-
  hw/s390x/sclpconsole.c |  323 
 
  2 files changed, 324 insertions(+), 1 deletions(-)
  create mode 100644 hw/s390x/sclpconsole.c

 diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
 index ed4e61a..096dfcd 100644
 --- a/hw/s390x/Makefile.objs
 +++ b/hw/s390x/Makefile.objs
 @@ -3,4 +3,4 @@ obj-y = s390-virtio-bus.o s390-virtio.o
  obj-y := $(addprefix ../,$(obj-y))
  obj-y += sclp.o
  obj-y += event-facility.o
 -obj-y += sclpquiesce.o
 +obj-y += sclpquiesce.o sclpconsole.o
 diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
 new file mode 100644
 index 000..9a57032
 --- /dev/null
 +++ b/hw/s390x/sclpconsole.c
 @@ -0,0 +1,323 @@
 +/*
 + * SCLP event type
 + *Ascii Console Data (VT220 Console)
 + *
 + * Copyright IBM, Corp. 2012
 + *
 + * Authors:
 + *  Heinz Graalfs graa...@de.ibm.com
 + *
 + * This work is licensed under the terms of the GNU GPL, version 2 or (at 
 your
 + * option) any later version.  See the COPYING file in the top-level 
 directory.
 + *
 + */
 +
 +#include hw/qdev.h
 +#include qemu-thread.h
 +
 +#include sclp.h
 +#include event-facility.h
 +
 +typedef struct ASCIIConsoleData {
 +EventBufferHeader ebh;
 +char data[0];
 +} QEMU_PACKED ASCIIConsoleData;
 +
 +qemu_irq sclp_read_vt220;

This should go into SCLPConsole.

 +
 +/* max size for ASCII data in 4K SCCB page */
 +#define SIZE_BUFFER_VT220 4080
 +
 +typedef struct SCLPConsole {
 +SCLPEvent event;
 +CharDriverState *chr;
 +/* io vector   */
 +uint8_t *iov;   /* iov buffer pointer  */
 +uint8_t *iov_sclp;  /* pointer to SCLP read offset */
 +uint8_t *iov_bs;/* pointer byte stream read offset */
 +uint32_t iov_data_len;  /* length of byte stream in buffer */
 +uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
 +} SCLPConsole;
 +
 +/* character layer call-back functions */
 +
 +/* Return number of bytes that fit into iov buffer */
 +static int chr_can_read(void *opaque)
 +{
 +int can_read;
 +SCLPConsole *scon = opaque;
 +
 +qemu_mutex_lock(scon-event.lock);
 +can_read = SIZE_BUFFER_VT220 - scon-iov_data_len;
 +qemu_mutex_unlock(scon-event.lock);
 +
 +return can_read;
 +}
 +
 +/* Receive n bytes from character layer, save in iov buffer,
 + * and set event pending */
 +static void receive_from_chr_layer(void *opaque, const uint8_t *buf, int 
 size)
 +{
 +SCLPConsole *scon = opaque;
 +
 +assert(scon-iov);
 +
 +qemu_mutex_lock(scon-event.lock);
 +
 +/* if new data do not fit into current buffer */
 +if (scon-iov_data_len + size  SIZE_BUFFER_VT220) {
 +/* character layer sent more than allowed */
 +qemu_mutex_unlock(scon-event.lock);
 +return;
 +}
 +/* put byte-stream from character layer into buffer */
 +memcpy(scon-iov_bs, buf, size);
 +scon-iov_data_len += size;
 +scon-iov_sclp_rest += size;
 +scon-iov_bs += size;
 +scon-event.event_pending = true;
 +
 +qemu_mutex_unlock(scon-event.lock);
 +}
 +
 +/* Send data from a char device over to the guest */
 +static void chr_read(void *opaque, const uint8_t *buf, int size)
 +{
 +assert(opaque);
 +

I'd convert the opaque to SCLPConsole here and use that for
receive_from_chr_layer() instead of opaque.

 +receive_from_chr_layer(opaque, buf, size);
 +/* trigger SCLP read operation */
 +qemu_irq_raise(sclp_read_vt220);
 +}
 +
 +static void chr_event(void *opaque, int event)
 +{
 +SCLPConsole *scon = opaque;
 +
 +switch (event) {
 +case CHR_EVENT_OPENED:
 +if (!scon-iov) {
 +scon-iov = g_malloc0(SIZE_BUFFER_VT220);
 +scon-iov_sclp = scon-iov;
 +

Re: [Qemu-devel] [PATCH v3 2/2] bitops: fix types

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 9:26 AM, Markus Armbruster arm...@redhat.com wrote:
 Peter Maydell peter.mayd...@linaro.org writes:

 On 23 July 2012 18:33, Blue Swirl blauwir...@gmail.com wrote:
 I'm getting a strong feeling that it's a bad idea to reuse any Linux
 kernel sources since they are seen as divine and untouchable, unlike
 for example BSD queue macros.

 Reusing good code that solves the problem at hand can be a bad idea if
 you can't resist the temptation to tinker with it, yet can't be bothered
 to upstream your improvements.  Then you might as well build your own
 bikeshed from scratch :)

There's nothing wrong in tinkering with reused good code. As I
explained, there's little point to upstream these changes, so 'not
bothering' is false accusation.


 We should also try to avoid deviations in our queue macros,

 Agree.

Avoiding deviations can be secondary to many other needs.


 and I think we do (eg commit 6095aa8 added functionality by
 moving us closer into sync with the BSD macros rather than
 by reinventing the wheel which was IIRC what the initial pre-code-review
 patch did).



Re: [Qemu-devel] [PATCH 2/2] fdc-test: Check RELATIVE SEEK beyond track 0/80

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 9:35 AM, Kevin Wolf kw...@redhat.com wrote:
 Am 23.07.2012 19:09, schrieb Blue Swirl:
 On Tue, Jul 17, 2012 at 9:03 AM, Pavel Hrdina phrd...@redhat.com wrote:
 I tested it on the real floppy and the behavior is more complicated.

 This reminds me of an idea: it could be interesting to make qtest test
 real hardware, for example using a serial port to feed commands and
 get responses. The same protocol which libqtest uses could be
 interpreted by a boot loader level program or kernel module.

 The existing qtest cases wouldn't necessarily work there because they
 don't care about timing. Not sure if it's worth the effort writing real
 drivers in qtest cases just to be able to run them against real hardware
 occasionally.

It would be nice if the tests paid some attention to timing, though
QEMU does not implement many timing issues either.

The benefit from this setup would be that the test suite would be
validated against real HW. But as the hardware gets older and breaks
down, it will be increasingly difficult to validate the suite in the
future so I also think it's probably not worth the effort.


 Kevin



Re: [Qemu-devel] [PATCH 15/47] blkdebug: process all set_state rules in the old state

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 11:03 AM, Paolo Bonzini pbonz...@redhat.com wrote:
 Currently it is impossible to write a blkdebug script that ping-pongs
 between two states, because the second set-state rule will use the
 state that is set in the first.  If you have

 [set-state]
 event = ...
 state = 1
 new_state = 2

 [set-state]
 event = ...
 state = 2
 new_state = 1

 for example the state will remain locked at 1.  This can be fixed
 by first processing all rules, and then setting the state.

 Signed-off-by: Paolo Bonzini pbonz...@redhat.com
 ---
  block/blkdebug.c |   14 +-
  1 file changed, 9 insertions(+), 5 deletions(-)

 diff --git a/block/blkdebug.c b/block/blkdebug.c
 index 59dcea0..0f12145 100644
 --- a/block/blkdebug.c
 +++ b/block/blkdebug.c
 @@ -28,6 +28,7 @@

  typedef struct BDRVBlkdebugState {
  int state;
 +int new_state;
  QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX];
  QSIMPLEQ_HEAD(, BlkdebugRule) active_rules;
  } BDRVBlkdebugState;
 @@ -351,6 +352,7 @@ static BlockDriverAIOCB 
 *blkdebug_aio_readv(BlockDriverState *bs,
  BDRVBlkdebugState *s = bs-opaque;
  BlkdebugRule *rule = NULL;

 +printf(read %ld\n, sector_num);

Leftover debugging?

  QSIMPLEQ_FOREACH(rule, s-active_rules, active_next) {
  if (rule-options.inject.sector == -1 ||
  (rule-options.inject.sector = sector_num 
 @@ -403,12 +405,12 @@ static void blkdebug_close(BlockDriverState *bs)
  }

  static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
 -int old_state, bool injected)
 +bool injected)
  {
  BDRVBlkdebugState *s = bs-opaque;

  /* Only process rules for the current state */
 -if (rule-state  rule-state != old_state) {
 +if (rule-state  rule-state != s-state) {
  return injected;
  }

 @@ -423,7 +425,7 @@ static bool process_rule(BlockDriverState *bs, struct 
 BlkdebugRule *rule,
  break;

  case ACTION_SET_STATE:
 -s-state = rule-options.set_state.new_state;
 +s-new_state = rule-options.set_state.new_state;
  break;
  }
  return injected;
 @@ -433,15 +435,17 @@ static void blkdebug_debug_event(BlockDriverState *bs, 
 BlkDebugEvent event)
  {
  BDRVBlkdebugState *s = bs-opaque;
  struct BlkdebugRule *rule;
 -int old_state = s-state;
  bool injected;

  assert((int)event = 0  event  BLKDBG_EVENT_MAX);

 +printf(state %d\n, s-state);

Here too?

  injected = false;
 +s-new_state = s-state;
  QLIST_FOREACH(rule, s-rules[event], next) {
 -injected = process_rule(bs, rule, old_state, injected);
 +injected = process_rule(bs, rule, injected);
  }
 +s-state = s-new_state;
  }

  static int64_t blkdebug_getlength(BlockDriverState *bs)
 --
 1.7.10.4






Re: [Qemu-devel] vhost-scsi port to v1.1.0 + MSI-X performance regression

2012-07-24 Thread Nicholas A. Bellinger
On Tue, 2012-07-24 at 09:57 +0200, Jan Kiszka wrote:
 On 2012-07-24 09:42, Nicholas A. Bellinger wrote:
  Hi Anthony, Stefan  QEMU folks,
  

SNIP

  However, thus far I've not been able to get virtio-scsi - tcm_vhost
  I/O to actually work against the latest qemu.git/master..  
  
  So while doing a (manual) bisection w/ this series to track down the
  issue with qemu/master, I managed to run across something else..  With
  the vhost-scsi series applied, everything is working as expected up
  until the following commit:
  
  commit 1523ed9e1d46b0b54540049d491475ccac7e6421
  Author: Jan Kiszka jan.kis...@siemens.com
  Date:   Thu May 17 10:32:39 2012 -0300
  
  virtio/vhost: Add support for KVM in-kernel MSI injection
  
  
  This commit ends up triggering the following assert immediately after
  starting qemu with virtio-scsi - tcm_vhost:
  
  qemu-system-x86_64: /usr/src/qemu.git/hw/msix.c:515:
 msix_unset_vector_notifiers: Assertion 
  `dev-msix_vector_use_notifier 
  dev-msix_vector_release_notifier' 
  failed.
  
  OK, so adding the following hack allows me to boot:
  
  diff --git a/hw/msix.c b/hw/msix.c
  index 59c7a83..6036909 100644
  --- a/hw/msix.c
  +++ b/hw/msix.c
  @@ -511,6 +511,11 @@ void msix_unset_vector_notifiers(PCIDevice *dev)
   {
   int vector;
   
  +if (!dev-msix_vector_use_notifier  
  !dev-msix_vector_release_notifier) {
  +printf(Hit NULL msix_unset_vector_notifiers for: %s\n, 
  dev-name);
  +return;
  +}
  +
   assert(dev-msix_vector_use_notifier 
  dev-msix_vector_release_notifier);
   
  --
 
 Can you post a backtrace from gdb?
 

Sure, w/o the above patch the backtrace with commit 1523ed9e1d looks
like the following:

(gdb) run
Starting program: /usr/src/qemu.git/x86_64-softmmu/qemu-system-x86_64 
-enable-kvm -smp 2 -m 2048 -serial file:/tmp/vhost-serial.txt -hda 
/usr/src/qemu-vhost.git/debian_squeeze_amd64_standard-old.qcow2 -vhost-scsi 
id=vhost-scsi0,wwpn=naa.600140579ad21088,tpgt=1 -device 
virtio-scsi-pci,vhost-scsi=vhost-scsi0,event_idx=off
[Thread debugging using libthread_db enabled]
wwpn = vhost-scsi0 tpgt = 1
[New Thread 0x745f8700 (LWP 26508)]
[New Thread 0x73bf6700 (LWP 26509)]
[New Thread 0x733f5700 (LWP 26510)]
vhost_scsi_stop
Failed to clear endpoint
qemu-system-x86_64: /usr/src/qemu.git/hw/msix.c:515: 
msix_unset_vector_notifiers: Assertion `dev-msix_vector_use_notifier  
dev-msix_vector_release_notifier' failed.

Program received signal SIGABRT, Aborted.
0x75e8b165 in raise () from /lib/libc.so.6
(gdb) bt
#0  0x75e8b165 in raise () from /lib/libc.so.6
#1  0x75e8df70 in abort () from /lib/libc.so.6
#2  0x75e842b1 in __assert_fail () from /lib/libc.so.6
#3  0x004a84a1 in msix_unset_vector_notifiers (dev=0x1463a70) at 
/usr/src/qemu.git/hw/msix.c:514
#4  0x004d2865 in virtio_pci_set_guest_notifiers (opaque=0x6788, 
assign=136)
at /usr/src/qemu.git/hw/virtio-pci.c:703
#5  0x0062955f in vhost_dev_stop (hdev=0x126c8a8, vdev=0x1465220) at 
/usr/src/qemu.git/hw/vhost.c:954
#6  0x00628989 in vhost_scsi_stop (vs=0x126c890, vdev=0x1465220) at 
/usr/src/qemu.git/hw/vhost-scsi.c:115
#7  0x0062f5c9 in virtio_scsi_set_status (vdev=0x1465220, val=value 
optimized out)
at /usr/src/qemu.git/hw/virtio-scsi.c:631
#8  0x00632082 in virtio_set_status (vdev=0x1465220, val=136 '\210') at 
/usr/src/qemu.git/hw/virtio.c:507
#9  0x00633410 in virtio_reset (opaque=0x6788) at 
/usr/src/qemu.git/hw/virtio.c:517
#10 0x004d30a9 in virtio_pci_reset (d=0x1463a70) at 
/usr/src/qemu.git/hw/virtio-pci.c:280
#11 0x004fc909 in qdev_reset_one (dev=0x6788, opaque=0x6788) at 
/usr/src/qemu.git/hw/qdev.c:207
#12 0x004fc670 in qdev_walk_children (dev=0x1463a70, devfn=0x4fc8f0 
qdev_reset_one, 
busfn=0x4fc510 qbus_reset_one, opaque=0x0) at 
/usr/src/qemu.git/hw/qdev.c:372
#13 0x004ae43d in pci_device_reset (dev=0x6788) at 
/usr/src/qemu.git/hw/pci.c:163
#14 0x004ae64f in pci_bus_reset (bus=0x1415bd0) at 
/usr/src/qemu.git/hw/pci.c:206
#15 0x004ae699 in pcibus_reset (qbus=0x6788) at 
/usr/src/qemu.git/hw/pci.c:213
#16 0x004fc710 in qbus_walk_children (bus=0x1415bd0, devfn=0x4fc8f0 
qdev_reset_one, busfn=0x6, opaque=0x0)
at /usr/src/qemu.git/hw/qdev.c:349
#17 0x004fc6a3 in qdev_walk_children (dev=value optimized out, 
devfn=0x4fc8f0 qdev_reset_one, 
busfn=0x4fc510 qbus_reset_one, opaque=0x0) at 
/usr/src/qemu.git/hw/qdev.c:379
#18 0x004fc745 in qbus_walk_children (bus=value optimized out, 
devfn=0x4fc8f0 qdev_reset_one, 
busfn=0x4fc510 qbus_reset_one, opaque=0x0) at 
/usr/src/qemu.git/hw/qdev.c:356
#19 0x004d5822 in qemu_system_reset (report=false) at 
/usr/src/qemu.git/vl.c:1412
#20 0x004d70bb in main (argc=value optimized out, argv=value 
optimized out, envp=value optimized out)
at 

Re: [Qemu-devel] [RFC PATCH 0/6] virtio-trace: Support virtio-trace

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 2:36 AM, Yoshihiro YUNOMAE
yoshihiro.yunomae...@hitachi.com wrote:
 Hi All,

 The following patch set provides a low-overhead system for collecting kernel
 tracing data of guests by a host in a virtualization environment.

 A guest OS generally shares some devices with other guests or a host, so
 reasons of any problems occurring in a guest may be from other guests or a 
 host.
 Then, to collect some tracing data of a number of guests and a host is needed
 when some problems occur in a virtualization environment. One of methods to
 realize that is to collect tracing data of guests in a host. To do this, 
 network
 is generally used. However, high load will be taken to applications on guests
 using network I/O because there are many network stack layers. Therefore,
 a communication method for collecting the data without using network is 
 needed.

I implemented something similar earlier by passing trace data from
OpenBIOS to QEMU using the firmware configuration device. The data
format was the same as QEMU used for simpletrace event structure
instead of ftrace. I didn't commit it because of a few problems.

I'm not familiar with ftrace, is it possible to trace two guest
applications (BIOS and kernel) at the same time? Or could this be
handled by opening two different virtio-serial pipes, one for BIOS and
the other for the kernel?

In my version, the tracepoint ID would have been used to demultiplex
QEMU tracepoints from BIOS tracepoints, but something like separate ID
spaces would have been better.


 We submitted a patch set of IVRing, a ring-buffer driver constructed on
 Inter-VM shared memory (IVShmem), to LKML http://lwn.net/Articles/500304/ in
 this June. IVRing and the IVRing reader use POSIX shared memory each other
 without using network, so a low-overhead system for collecting guest tracing
 data is realized. However, this patch set has some problems as follows:
  - use IVShmem instead of virtio
  - create a new ring-buffer without using existing ring-buffer in kernel
  - scalability
-- not support SMP environment
-- buffer size limitation
-- not support live migration (maybe difficult for realize this)

 Therefore, we propose a new system virtio-trace, which uses enhanced
 virtio-serial and existing ring-buffer of ftrace, for collecting guest kernel
 tracing data. In this system, there are 5 main components:
  (1) Ring-buffer of ftrace in a guest
  - When trace agent reads ring-buffer, a page is removed from ring-buffer.
  (2) Trace agent in the guest
  - Splice the page of ring-buffer to read_pipe using splice() without
memory copying. Then, the page is spliced from write_pipe to virtio
without memory copying.
  (3) Virtio-console driver in the guest
  - Pass the page to virtio-ring
  (4) Virtio-serial bus in QEMU
  - Copy the page to kernel pipe
  (5) Reader in the host
  - Read guest tracing data via FIFO(named pipe)

 ***Evaluation***
 When a host collects tracing data of a guest, the performance of using
 virtio-trace is compared with that of using native(just running ftrace),
 IVRing, and virtio-serial(normal method of read/write).

 environment
 The overview of this evaluation is as follows:
  (a) A guest on a KVM is prepared.
  - The guest is dedicated one physical CPU as a virtual CPU(VCPU).

  (b) The guest starts to write tracing data to ring-buffer of ftrace.
  - The probe points are all trace points of sched, timer, and kmem.

  (c) Writing trace data, dhrystone 2 in UNIX bench is executed as a benchmark
  tool in the guest.
  - Dhrystone 2 intends system performance by repeating integer arithmetic
as a score.
  - Since higher score equals to better system performance, if the score
decrease based on bare environment, it indicates that any operation
disturbs the integer arithmetic. Then, we define the overhead of
transporting trace data is calculated as follows:
 OVERHEAD = (1 - SCORE_OF_A_METHOD/NATIVE_SCORE) * 100.

 The performance of each method is compared as follows:
  [1] Native
  - only recording trace data to ring-buffer on a guest
  [2] Virtio-trace
  - running a trace agent on a guest
  - a reader on a host opens FIFO using cat command
  [3] IVRing
  - A SystemTap script in a guest records trace data to IVRing.
-- probe points are same as ftrace.
  [4] Virtio-serial(normal)
  - A reader(using cat) on a guest output trace data to a host using
standard output via virtio-serial.

 Other information is as follows:
  - host
kernel: 3.3.7-1 (Fedora16)
CPU: Intel Xeon x5660@2.80GHz(12core)
Memory: 48GB

  - guest(only booting one guest)
kernel: 3.5.0-rc4+ (Fedora16)
CPU: 1VCPU(dedicated)
Memory: 1GB

 result
 3 patterns based on the bare environment were indicated as follows:
Scores  overhead against [0] Native
 [0] Native:  28807569.5   

Re: [Qemu-devel] [PATCH] tcm_vhost: Expose ABI version via VHOST_SCSI_GET_ABI_VERSION

2012-07-24 Thread Nicholas A. Bellinger
On Mon, 2012-07-23 at 18:56 -0700, Greg Kroah-Hartman wrote:
 On Tue, Jul 24, 2012 at 01:26:20AM +, Nicholas A. Bellinger wrote:
  From: Nicholas Bellinger n...@linux-iscsi.org
  
  As requested by Anthony, here is a patch against 
  target-pending/for-next-merge
  to expose an ABI version to userspace via a new VHOST_SCSI_GET_ABI_VERSION
  ioctl operation.
  
  As mentioned in the comment, ABI Rev 0 is for pre 2012 out-of-tree code, and
  ABI Rev 1 (the current rev) is for current WIP v3.6 kernel merge candiate 
  code.
  
  I think this is what you had in mind, and hopefully it will make MST happy 
  too.
  The incremental vhost-scsi patches against Zhi's QEMU are going out shortly 
  ahead
  of cutting a new vhost-scsi RFC over the next days.
  
  Please have a look and let me know if you have any concerns here.
  
  Thanks!
  
  Reported-by: Anthony Liguori aligu...@us.ibm.com
  Cc: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
  Cc: Michael S. Tsirkin m...@redhat.com
  Cc: Paolo Bonzini pbonz...@redhat.com
  Cc: Zhi Yong Wu wu...@linux.vnet.ibm.com
  Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
  ---
   drivers/vhost/tcm_vhost.c |9 +
   drivers/vhost/tcm_vhost.h |   11 +++
   2 files changed, 20 insertions(+), 0 deletions(-)
  

SNIP

  diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h
  index e942df9..3d5378f 100644
  --- a/drivers/vhost/tcm_vhost.h
  +++ b/drivers/vhost/tcm_vhost.h
  @@ -80,7 +80,17 @@ struct tcm_vhost_tport {
   
   #include linux/vhost.h
   
  +/*
  + * Used by QEMU userspace to ensure a consistent vhost-scsi ABI.
  + *
  + * ABI Rev 0: All pre 2012 revisions used by prototype out-of-tree code
  + * ABI Rev 1: 2012 version for v3.6 kernel merge candiate
  + */
  +
  +#define VHOST_SCSI_ABI_VERSION 1
  +
   struct vhost_scsi_target {
  +   int abi_version;
  unsigned char vhost_wwpn[TRANSPORT_IQN_LEN];
  unsigned short vhost_tpgt;
   };
  @@ -88,3 +98,4 @@ struct vhost_scsi_target {
   /* VHOST_SCSI specific defines */
   #define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct 
  vhost_scsi_target)
   #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct 
  vhost_scsi_target)
  +#define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct 
  vhost_scsi_target)
 
 No, you just broke the ABI for version 0 here, that's not how you do
 this at all.
 

The intention of this patch is use ABI=1 as a starting point for
tcm_vhost moving forward, with no back-wards compat for the ABI=0
prototype userspace code because:

- It's based on a slightly older version of QEMU (updating the QEMU series now)
- It does not have an GET_ABI_VERSION ioctl cmd (that starts with ABI=1)
- It has a small user-base of target + virtio-scsi developers

So I did consider just starting from ABI=0, but figured this would help
reduce the confusion for QEMU userspace wrt to the vhost-scsi code
that's been floating around out-of-tree for the last 2 years.

Stefan  Co folks, do you have a preference for a starting point..?

Thanks,

--nab




Re: [Qemu-devel] [PATCH 18/22] qidl: qidl.h

2012-07-24 Thread Blue Swirl
On Tue, Jul 24, 2012 at 5:20 PM, Michael Roth mdr...@linux.vnet.ibm.com wrote:

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  qidl.h |   58 ++
  1 file changed, 58 insertions(+)
  create mode 100644 qidl.h

 diff --git a/qidl.h b/qidl.h
 new file mode 100644
 index 000..75ae5af
 --- /dev/null
 +++ b/qidl.h
 @@ -0,0 +1,58 @@
 +/*
 + * QEMU IDL Macros/stubs
 + *
 + * See docs/qidl.txt for usage information.
 + *
 + * Copyright IBM, Corp. 2012
 + *
 + * Authors:
 + *  Michael Rothmdr...@linux.vnet.ibm.com
 + *
 + * This work is licensed under the terms of the GNU GPLv2.

GPLv2 or later?

 + * See the COPYING file in the top-level directory.
 + *
 + */
 +
 +#ifndef QIDL_H
 +#define QIDL_H
 +
 +#include qapi/qapi-visit-core.h
 +#include qemu/object.h
 +#include hw/qdev-properties.h
 +
 +#ifdef QIDL_GEN
 +
 +/* we pass the code through the preprocessor with QIDL_GEN defined to parse
 + * structures as they'd appear after preprocessing, and use the following
 + * definitions mostly to re-insert the initial macros/annotations so they
 + * stick around for the parser to process

I guess this doesn't work if the file #includes itself, like some
flash files used to do (or I can't find the example just now).

 + */
 +#define QIDL(...) QIDL(__VA_ARGS__)
 +#define QIDL_START(...) QIDL_START(__VA_ARGS__)
 +#define QIDL_END(...) QIDL_END(__VA_ARGS__)
 +
 +#define QIDL_VISIT_TYPE(...)
 +#define QIDL_SCHEMA_ADD_LINK(...)
 +#define QIDL_PROPERTIES(...)

Maybe for this pass, the macros which do nothing like above could
still do more syntax checking by specifying the macro argument list
instead of ellipsis or even by introducing a dummy inline function.

 +
 +#else /* !QIDL_GEN */
 +
 +#define QIDL(...)
 +#define QIDL_START(name, ...)

Declare 'struct type of name' here (see below)?

 +#define QIDL_END(name) \
 +static struct { \

'const', how about a name for the struct type too?

 +void (*visitor)(Visitor *, struct name **, const char *, Error **); \

Here 'struct name **' could be const if the struct defined here is
const. Probably 'struct name' should be declared earlier.

 +const char *schema_json_text; \
 +Object *schema_obj; \
 +Property *properties; \
 +} qidl_data_##name;
 +
 +#define QIDL_VISIT_TYPE(name, v, s, f, e) qidl_data_##name.visitor(v, s, f, 
 e)
 +#define QIDL_SCHEMA_ADD_LINK(name, obj, path, errp) \
 +object_property_add_link(obj, path, container, \
 + qidl_data_##name.schema_obj, errp);

The semicolons here and below seem useless.

 +#define QIDL_PROPERTIES(name) qidl_data_##name.properties;
 +
 +#endif /* QIDL_GEN */
 +
 +#endif
 --
 1.7.9.5





Re: [Qemu-devel] vhost-scsi port to v1.1.0 + MSI-X performance regression

2012-07-24 Thread Nicholas A. Bellinger
On Tue, 2012-07-24 at 13:20 -0700, Nicholas A. Bellinger wrote:
 On Tue, 2012-07-24 at 09:57 +0200, Jan Kiszka wrote:
  On 2012-07-24 09:42, Nicholas A. Bellinger wrote:
   Hi Anthony, Stefan  QEMU folks,
   
 
 SNIP
 
   However, thus far I've not been able to get virtio-scsi - tcm_vhost
   I/O to actually work against the latest qemu.git/master..  
   
   So while doing a (manual) bisection w/ this series to track down the
   issue with qemu/master, I managed to run across something else..  With
   the vhost-scsi series applied, everything is working as expected up
   until the following commit:
   
   commit 1523ed9e1d46b0b54540049d491475ccac7e6421
   Author: Jan Kiszka jan.kis...@siemens.com
   Date:   Thu May 17 10:32:39 2012 -0300
   
   virtio/vhost: Add support for KVM in-kernel MSI injection
   
   
   This commit ends up triggering the following assert immediately after
   starting qemu with virtio-scsi - tcm_vhost:
   
   qemu-system-x86_64: /usr/src/qemu.git/hw/msix.c:515:
  msix_unset_vector_notifiers: Assertion 
   `dev-msix_vector_use_notifier 
   dev-msix_vector_release_notifier' 
   failed.
   
   OK, so adding the following hack allows me to boot:

SNIP

  Also, is there a git tree and a way to reproduce this without special
  hardware needs?
  
 
 I'll push this series + branches to demonstrate the issue into an public
 tree this afternoon.
 

OK, the updated vhost-scsi QEMU working tree is now available here:

http://git.kernel.org/?p=virt/kvm/nab/qemu-kvm.git;a=summary

Please ignore the qemu-kvm.git name for the moment, as it really is
based on upstream qemu.  ;)

The branch breakdown looks like:

  master401a663 remove unused QemuOpts parameter from net init 
functions
* vhost-scsibdd00bd msix: Add msix_nr_vectors_allocated
  vhost-scsi-merge  e4fdb8c [ahead 9] vhost-scsi: add -vhost-scsi host 
device
  vhost-scsi-workaround 32ed0db msix: Work-around for vhost-scsi with KVM 
in-kernel MSI injection

- 'vhost-scsi' contains vhost-scsi patches + pre commit 1523ed9e1d logic
   (Running stable at ~67.5K IOPs, see below)
- 'vhost-scsi-merge' contains a vhost-scsi series against yesterday's qemu.git 
HEAD
   (not working atm, but will be sending out for RFC shortly)
- 'vhost-scsi-workaround' contains the msix.c workaround to get commit 
1523ed9e1d to boot
   (reproducible performance regression, down to 6K IOPs)

 Also, the particular backend is a Fusion-IO raw block flash device, but
 I'm pretty sure that using a TCM RAMDISK into tcm_vhost would exhibit
 the same type of behavior.  (Will double check on that shortly..)
 

Interestingly enough, after running some test with the vhost-scsi branch
above with the last good working commit (bdd00bd), the same fio
benchmark inline below is now reaching ~67.5K IOPs using v3.5-rc2 guest
+ host..

rw=randrw
rwmixwrite=25
rwmixread=75
size=32768m
ioengine=libaio
direct=1
iodepth=64
blocksize=4k
numjobs=2
filename=/dev/sdb


This ends up being within a few percentage of what the bare-metal HW is
capable of.. (~70K IOPs per LUN for an ioDrive Duo, Jen's CC'ed).  Note
the older QEMU vhost-scsi tree based on pre 1.1.0 code was doing ~60K
IOPs for the same test..

So this looks promising pre commit 1523ed9e1d vs. what we've been using
with vhost-scsi so far..  ;)

--nab




Re: [Qemu-devel] [PATCH 04/22] qapi: qapi_visit.py, make code useable as module

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  scripts/qapi_visit.py |  143 
 +
  1 file changed, 74 insertions(+), 69 deletions(-)

 diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
 index 04ef7c4..25707f5 100644
 --- a/scripts/qapi_visit.py
 +++ b/scripts/qapi_visit.py
 @@ -224,55 +224,57 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, 
 const char *name, Error **e
  ''',
  name=name)
  
 -try:
 -opts, args = getopt.gnu_getopt(sys.argv[1:], chp:o:,
 -   [source, header, prefix=, 
 output-dir=])
 -except getopt.GetoptError, err:
 -print str(err)
 -sys.exit(1)
 -
 -output_dir = 
 -prefix = 
 -c_file = 'qapi-visit.c'
 -h_file = 'qapi-visit.h'
 -
 -do_c = False
 -do_h = False
 -
 -for o, a in opts:
 -if o in (-p, --prefix):
 -prefix = a
 -elif o in (-o, --output-dir):
 -output_dir = a + /
 -elif o in (-c, --source):
 +def main(argv=[]):
 +try:
 +opts, args = getopt.gnu_getopt(sys.argv[1:], chp:o:,
 +   [source, header, prefix=,
 +output-dir=])
 +except getopt.GetoptError, err:
 +print str(err)
 +sys.exit(1)
 +
 +output_dir = 
 +prefix = 
 +c_file = 'qapi-visit.c'
 +h_file = 'qapi-visit.h'
 +
 +do_c = False
 +do_h = False
 +
 +for o, a in opts:
 +if o in (-p, --prefix):
 +prefix = a
 +elif o in (-o, --output-dir):
 +output_dir = a + /
 +elif o in (-c, --source):
 +do_c = True
 +elif o in (-h, --header):
 +do_h = True
 +
 +if not do_c and not do_h:
  do_c = True
 -elif o in (-h, --header):
  do_h = True
  
 -if not do_c and not do_h:
 -do_c = True
 -do_h = True
 +c_file = output_dir + prefix + c_file
 +h_file = output_dir + prefix + h_file
  
 -c_file = output_dir + prefix + c_file
 -h_file = output_dir + prefix + h_file
 +try:
 +os.makedirs(output_dir)
 +except os.error, e:
 +if e.errno != errno.EEXIST:
 +raise
  
 -try:
 -os.makedirs(output_dir)
 -except os.error, e:
 -if e.errno != errno.EEXIST:
 -raise
 -
 -def maybe_open(really, name, opt):
 -if really:
 -return open(name, opt)
 -else:
 -import StringIO
 -return StringIO.StringIO()
 +def maybe_open(really, name, opt):
 +if really:
 +return open(name, opt)
 +else:
 +import StringIO
 +return StringIO.StringIO()
  
 -fdef = maybe_open(do_c, c_file, 'w')
 -fdecl = maybe_open(do_h, h_file, 'w')
 +fdef = maybe_open(do_c, c_file, 'w')
 +fdecl = maybe_open(do_h, h_file, 'w')
  
 -fdef.write(mcgen('''
 +fdef.write(mcgen('''
  /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
  
  /*
 @@ -292,7 +294,7 @@ fdef.write(mcgen('''
  ''',
   header=basename(h_file)))
  
 -fdecl.write(mcgen('''
 +fdecl.write(mcgen('''
  /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
  
  /*
 @@ -316,37 +318,40 @@ fdecl.write(mcgen('''
  ''',
prefix=prefix, guard=guardname(h_file)))
  
 -exprs = parse_schema(sys.stdin)
 +exprs = parse_schema(sys.stdin)
  
 -for expr in exprs:
 -if expr.has_key('type'):
 -ret = generate_visit_struct(expr['type'], expr['data'])
 -ret += generate_visit_list(expr['type'], expr['data'])
 -fdef.write(ret)
 +for expr in exprs:
 +if expr.has_key('type'):
 +ret = generate_visit_struct(expr['type'], expr['data'])
 +ret += generate_visit_list(expr['type'], expr['data'])
 +fdef.write(ret)
  
 -ret = generate_declaration(expr['type'], expr['data'])
 -fdecl.write(ret)
 -elif expr.has_key('union'):
 -ret = generate_visit_union(expr['union'], expr['data'])
 -ret += generate_visit_list(expr['union'], expr['data'])
 -fdef.write(ret)
 +ret = generate_declaration(expr['type'], expr['data'])
 +fdecl.write(ret)
 +elif expr.has_key('union'):
 +ret = generate_visit_union(expr['union'], expr['data'])
 +ret += generate_visit_list(expr['union'], expr['data'])
 +fdef.write(ret)
  
 -ret = generate_decl_enum('%sKind' % expr['union'], 
 expr['data'].keys())
 -ret += generate_declaration(expr['union'], expr['data'])
 -fdecl.write(ret)
 -elif expr.has_key('enum'):
 -ret = generate_visit_enum(expr['enum'], expr['data'])
 -fdef.write(ret)
 +ret = generate_decl_enum('%sKind' % expr['union'], 
 expr['data'].keys())
 +ret += generate_declaration(expr['union'], expr['data'])
 +

Re: [Qemu-devel] [PATCH 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori

 Add support for arrays in the code generators.

 Complex field descriptions can now be used to provide additional
 information to the visitor generators, such as the max size of an array,
 or the field within a struct to use to determine how many elements are
 present in the array to avoid serializing uninitialized elements.

 Add handling for these in the code generators as well.

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  scripts/qapi.py  |   10 --
  scripts/qapi_commands.py |8 
  scripts/qapi_types.py|2 +-
  scripts/qapi_visit.py|   34 +++---
  4 files changed, 40 insertions(+), 14 deletions(-)

 diff --git a/scripts/qapi.py b/scripts/qapi.py
 index 8082af3..39bb74e 100644
 --- a/scripts/qapi.py
 +++ b/scripts/qapi.py
 @@ -99,12 +99,16 @@ def parse_args(typeinfo):
  argentry = typeinfo[member]
  optional = False
  structured = False
 +annotated = False
  if member.startswith('*'):
  argname = member[1:]
  optional = True
  if isinstance(argentry, OrderedDict):
 -structured = True
 -yield (argname, argentry, optional, structured)
 +if argentry.has_key('annotated'):
 +annotated = True
 +else:
 +structured = True
 +yield (argname, argentry, optional, structured, annotated)
  
  def de_camel_case(name):
  new_name = ''
 @@ -177,6 +181,8 @@ def c_type(name):
  return 'void'
  elif name == name.upper():
  return '%sEvent *' % camel_case(name)
 +elif name.replace(u, ).replace(int, ) in [8, 16, 32, 64]:
 +return name + _t
  else:
  return '%s *' % name
  
 diff --git a/scripts/qapi_commands.py b/scripts/qapi_commands.py
 index 9eed40e..52221d6 100644
 --- a/scripts/qapi_commands.py
 +++ b/scripts/qapi_commands.py
 @@ -32,7 +32,7 @@ void %(visitor)s(Visitor *m, %(name)s * obj, const char 
 *name, Error **errp);
  
  def generate_command_decl(name, args, ret_type):
  arglist=
 -for argname, argtype, optional, structured in parse_args(args):
 +for argname, argtype, optional, structured, annotated in 
 parse_args(args):
  argtype = c_type(argtype)
  if argtype == char *:
  argtype = const char *
 @@ -50,7 +50,7 @@ def gen_sync_call(name, args, ret_type, indent=0):
  retval=
  if ret_type:
  retval = retval = 
 -for argname, argtype, optional, structured in parse_args(args):
 +for argname, argtype, optional, structured, annotated in 
 parse_args(args):
  if optional:
  arglist += has_%s,  % c_var(argname)
  arglist += %s,  % (c_var(argname))
 @@ -106,7 +106,7 @@ Visitor *v;
  def gen_visitor_input_vars_decl(args):
  ret = 
  push_indent()
 -for argname, argtype, optional, structured in parse_args(args):
 +for argname, argtype, optional, structured, annotated in 
 parse_args(args):
  if optional:
  ret += mcgen('''
  bool has_%(argname)s = false;
 @@ -145,7 +145,7 @@ v = qmp_input_get_visitor(mi);
  ''',
   obj=obj)
  
 -for argname, argtype, optional, structured in parse_args(args):
 +for argname, argtype, optional, structured, annotated in 
 parse_args(args):
  if optional:
  ret += mcgen('''
  visit_start_optional(v, has_%(c_name)s, %(name)s, errp);
 diff --git a/scripts/qapi_types.py b/scripts/qapi_types.py
 index 4a734f5..fb2b9ea 100644
 --- a/scripts/qapi_types.py
 +++ b/scripts/qapi_types.py
 @@ -35,7 +35,7 @@ struct %(name)s
  ''',
name=structname)
  
 -for argname, argentry, optional, structured in parse_args(members):
 +for argname, argentry, optional, structured, annotated in 
 parse_args(members):
  if optional:
  ret += mcgen('''
  bool has_%(c_name)s;
 diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
 index 25707f5..9839e3c 100644
 --- a/scripts/qapi_visit.py
 +++ b/scripts/qapi_visit.py
 @@ -16,6 +16,22 @@ import sys
  import os
  import getopt
  import errno
 +import types
 +
 +def generate_visit_array_body(name, info):
 +ret = mcgen('''
 +visit_start_array(m, (void **)obj, %(name)s, %(count)s, sizeof(%(type)s), 
 errp);
 +int %(name)s_i;
 +for (%(name)s_i = 0; %(name)s_i  %(count)s; %(name)s_i++) {
 +visit_type_%(type_short)s(m, (*obj)-%(name)s[%(name)s_i], NULL, errp);
 +visit_next_array(m, errp);
 +}
 +visit_end_array(m, errp);
 +''',
 +name=name, type=c_type(info['type'][0]),
 +type_short=info['type'][0],
 +count=info['array_size'])
 +return ret
  
  def generate_visit_struct_body(field_prefix, name, members):
  ret = mcgen('''
 @@ -45,10 +61,10 @@ if (!err) {
  
  push_indent()
  

Re: [Qemu-devel] [PATCH 07/22] qapi: qapi_visit.py, support generating static functions

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori

 qidl embeds visitor code into object files rather than linking against
 seperate files, so allow for static declarations when we're using
 qapi_visit.py as a library as we do with qidl.py

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  scripts/qapi_visit.py |   51 
 -
  1 file changed, 33 insertions(+), 18 deletions(-)

 diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
 index bf93bfe..864acb2 100644
 --- a/scripts/qapi_visit.py
 +++ b/scripts/qapi_visit.py
 @@ -139,13 +139,16 @@ visit_end_optional(m, err);
  ''')
  return ret
  
 -def generate_visit_struct(name, members):
 +def generate_visit_struct(name, members, static=False):
 +ret_type = void
 +if static:
 +ret_type = static  + ret_type
  ret = mcgen('''
  
 -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, 
 Error **errp)
 +%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char 
 *name, Error **errp)
  {
  ''',
 -name=name)
 +name=name, ret_type=ret_type)
  
  push_indent()
  ret += generate_visit_struct_body(, name, members)
 @@ -156,10 +159,13 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, 
 const char *name, Error **
  ''')
  return ret
  
 -def generate_visit_list(name, members):
 +def generate_visit_list(name, members, static=False):
 +ret_type = void
 +if static:
 +ret_type = static  + ret_type
  return mcgen('''
  
 -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
 *name, Error **errp)
 +%(ret_type)s visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const 
 char *name, Error **errp)
  {
  GenericList *i, **prev = (GenericList **)obj;
  Error *err = NULL;
 @@ -181,19 +187,22 @@ void visit_type_%(name)sList(Visitor *m, %(name)sList 
 ** obj, const char *name,
  }
  }
  ''',
 -name=name)
 +name=name, ret_type=ret_type)
  
 -def generate_visit_enum(name, members):
 +def generate_visit_enum(name, members, static=False):
 +ret_type = void
 +if static:
 +ret_type = static  + ret_type
  return mcgen('''
  
 -void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error 
 **errp)
 +%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s * obj, const char 
 *name, Error **errp)
  {
  visit_type_enum(m, (int *)obj, %(name)s_lookup, %(name)s, name, errp);
  }
  ''',
 - name=name)
 + name=name, ret_type=ret_type)
  
 -def generate_visit_union(name, members):
 +def generate_visit_union(name, members, static=False):
  ret = generate_visit_enum('%sKind' % name, members.keys())
  
  ret += mcgen('''
 @@ -250,27 +259,33 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, 
 const char *name, Error **
  
  return ret
  
 -def generate_declaration(name, members, genlist=True):
 +def generate_declaration(name, members, genlist=True, static=False):
 +ret_type = void
 +if static:
 +ret_type = static  + ret_type
  ret = mcgen('''
  
 -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, 
 Error **errp);
 +%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char 
 *name, Error **errp);
  ''',
 -name=name)
 +name=name, ret_type=ret_type)
  
  if genlist:
  ret += mcgen('''
 -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
 *name, Error **errp);
 +%(ret_type)s visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const 
 char *name, Error **errp);
  ''',
 - name=name)
 + name=name, ret_type=ret_type)
  
  return ret
  
 -def generate_decl_enum(name, members, genlist=True):
 +def generate_decl_enum(name, members, genlist=True, static=False):
 +ret_type = void
 +if static:
 +ret_type = static  + ret_type
  return mcgen('''
  
 -void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error 
 **errp);
 +%(ret_type)s visit_type_%(name)s(Visitor *m, %(name)s * obj, const char 
 *name, Error **errp);
  ''',
 -name=name)
 +name=name, ret_type=ret_type)
  
  def main(argv=[]):
  try:
 -- 
 1.7.9.5




Re: [Qemu-devel] [PATCH 06/22] qapi: add visitor interfaces for arrays

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  qapi/qapi-visit-core.c |   25 +
  qapi/qapi-visit-core.h |8 
  scripts/qapi_visit.py  |   28 
  3 files changed, 61 insertions(+)

 diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
 index 7a82b63..631387d 100644
 --- a/qapi/qapi-visit-core.c
 +++ b/qapi/qapi-visit-core.c
 @@ -311,3 +311,28 @@ void input_type_enum(Visitor *v, int *obj, const char 
 *strings[],
  g_free(enum_str);
  *obj = value;
  }
 +
 +void visit_start_array(Visitor *v, void **obj, const char *name,
 +   size_t elem_count, size_t elem_size, Error
 **errp)

So this is a C style single dimension array?  Can we at least call this
c_array then or something like that.

Regards,

Anthony Liguori

 +{
 +g_assert(v-start_array);
 +if (!error_is_set(errp)) {
 +v-start_array(v, obj, name, elem_count, elem_size, errp);
 +}
 +}
 +
 +void visit_next_array(Visitor *v, Error **errp)
 +{
 +g_assert(v-next_array);
 +if (!error_is_set(errp)) {
 +v-next_array(v, errp);
 +}
 +}
 +
 +void visit_end_array(Visitor *v, Error **errp)
 +{
 +g_assert(v-end_array);
 +if (!error_is_set(errp)) {
 +v-end_array(v, errp);
 +}
 +}
 diff --git a/qapi/qapi-visit-core.h b/qapi/qapi-visit-core.h
 index 60aceda..4a7bdb6 100644
 --- a/qapi/qapi-visit-core.h
 +++ b/qapi/qapi-visit-core.h
 @@ -43,6 +43,10 @@ struct Visitor
  void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
  void (*type_number)(Visitor *v, double *obj, const char *name,
  Error **errp);
 +void (*start_array)(Visitor *v, void **obj, const char *name,
 +size_t elem_count, size_t elem_size, Error **errp);
 +void (*next_array)(Visitor *v, Error **errp);
 +void (*end_array)(Visitor *v, Error **errp);
  
  /* May be NULL */
  void (*start_optional)(Visitor *v, bool *present, const char *name,
 @@ -91,5 +95,9 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char 
 *name, Error **errp);
  void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
  void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
  void visit_type_number(Visitor *v, double *obj, const char *name, Error 
 **errp);
 +void visit_start_array(Visitor *v, void **obj, const char *name,
 +   size_t elem_count, size_t elem_size, Error **errp);
 +void visit_next_array(Visitor *v, Error **errp);
 +void visit_end_array(Visitor *v, Error **errp);
  
  #endif
 diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
 index 9839e3c..bf93bfe 100644
 --- a/scripts/qapi_visit.py
 +++ b/scripts/qapi_visit.py
 @@ -33,6 +33,34 @@ visit_end_array(m, errp);
  count=info['array_size'])
  return ret
  
 +def generate_visit_array_body(name, info):
 +if info['array_size'][0].isdigit():
 +array_size = info['array_size']
 +elif info['array_size'][0] == '(' and info['array_size'][-1] == ')':
 +array_size = info['array_size']
 +else:
 +array_size = (*obj)-%s % info['array_size']
 +
 +if info.has_key('array_capacity'):
 +array_capacity = info['array_capacity']
 +else:
 +array_capacity = array_size
 +
 +ret = mcgen('''
 +visit_start_array(m, (void **)obj, %(name)s, %(array_capacity)s, 
 sizeof(%(type)s), errp);
 +int %(name)s_i;
 +for (%(name)s_i = 0; %(name)s_i  %(array_size)s; %(name)s_i++) {
 +visit_type_%(type_short)s(m, (*obj)-%(name)s[%(name)s_i], NULL, errp);
 +visit_next_array(m, errp);
 +}
 +visit_end_array(m, errp);
 +''',
 +name=name, type=c_type(info['type'][0]),
 +type_short=info['type'][0],
 +array_size=array_size,
 +array_capacity=array_capacity)
 +return ret
 +
  def generate_visit_struct_body(field_prefix, name, members):
  ret = mcgen('''
  if (!error_is_set(errp)) {
 -- 
 1.7.9.5




Re: [Qemu-devel] [PATCH 08/22] qapi: qapi_visit.py, support for visiting non-pointer/embedded structs

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  scripts/qapi_visit.py |9 +
  1 file changed, 9 insertions(+)

 diff --git a/scripts/qapi_visit.py b/scripts/qapi_visit.py
 index 864acb2..8f8cdca 100644
 --- a/scripts/qapi_visit.py
 +++ b/scripts/qapi_visit.py
 @@ -105,6 +105,15 @@ if (obj  (*obj)-%(prefix)shas_%(c_name)s) {
  if annotated:
  if isinstance(argentry['type'], types.ListType):
  ret += generate_visit_array_body(argname, argentry)
 +elif argentry.has_key('embedded struct'):
 +tmp_ptr_name = %s_%s_ptr % 
 (c_var(field_prefix).replace(., ), c_var(argname))
 +ret += mcgen('''
 +%(type)s *%(tmp_ptr)s = (*obj)-%(c_prefix)s%(c_name)s;
 +visit_type_%(type)s(m, (obj  *obj) ? %(tmp_ptr)s : NULL, %(name)s, 
 errp);
 +''',
 + c_prefix=c_var(field_prefix), 
 prefix=field_prefix,
 + type=type_name(argentry['type']), 
 c_name=c_var(argname),
 + name=argname, tmp_ptr=tmp_ptr_name)
  else:
  ret += mcgen('''
  visit_type_%(type)s(m, obj ? (*obj)-%(c_prefix)s%(c_name)s : NULL, 
 %(name)s, errp);
 -- 
 1.7.9.5




Re: [Qemu-devel] [PATCH 12/22] qom-fuse: workaround for truncated properties 4096

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

I don't think this is the most correct solution but I think it's good
enough in practice so

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori

 We currently hard-code property size at 4096 for the purposes of
 getattr()/stat()/etc. For 'state' properties we can exceed this easily,
 leading to truncated responses.

 Instead, for a particular property, make it
 max(4096, most_recent_property_size * 2). This allows some
 head-room for properties that change size periodically (numbers,
 strings, state properties containing arrays, etc)

 Also, implement a simple property cache to avoid spinning on qom-get
 if an application reads beyond the actual size. This also allows us
 to use a snapshot of a single qom-get that persists across read()'s.
 Old Cache entries are evicted as soon as we attempt to read() from
 offset 0 again.

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  QMP/qom-fuse |   24 +---
  1 file changed, 17 insertions(+), 7 deletions(-)

 diff --git a/QMP/qom-fuse b/QMP/qom-fuse
 index 5c6754a..bd43f29 100755
 --- a/QMP/qom-fuse
 +++ b/QMP/qom-fuse
 @@ -26,6 +26,7 @@ class QOMFS(Fuse):
  self.qmp.connect()
  self.ino_map = {}
  self.ino_count = 1
 +self.prop_cache = {}
  
  def get_ino(self, path):
  if self.ino_map.has_key(path):
 @@ -67,12 +68,16 @@ class QOMFS(Fuse):
  if not self.is_property(path):
  return -ENOENT
  
 -path, prop = path.rsplit('/', 1)
 -try:
 -data = str(self.qmp.command('qom-get', path=path, property=prop))
 -data += '\n' # make values shell friendly
 -except:
 -return -EPERM
 +# avoid extra calls to qom-get by using cached value when offset  0
 +if offset == 0 or not self.prop_cache.has_key(path):
 +directory, prop = path.rsplit('/', 1)
 +try:
 +resp = str(self.qmp.command('qom-get', path=directory, 
 property=prop))
 +self.prop_cache[path] = resp + '\n' # make values shell 
 friendly
 +except:
 +return -EPERM
 +
 +data = self.prop_cache[path]
  
  if offset  len(data):
  return ''
 @@ -111,13 +116,18 @@ class QOMFS(Fuse):
 0,
 0))
  elif self.is_property(path):
 +directory, prop = path.rsplit('/', 1)
 +try:
 +resp = str(self.qmp.command('qom-get', path=directory, 
 property=prop))
 +except:
 +return -ENOENT
  value = posix.stat_result((0644 | stat.S_IFREG,
 self.get_ino(path),
 0,
 1,
 1000,
 1000,
 -   4096,
 +   max(len(resp) * 2, 4096),
 0,
 0,
 0))
 -- 
 1.7.9.5




Re: [Qemu-devel] [PATCH 14/22] qdev: move Property-related declarations to qdev-properties.h

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

License please.

Regards,

Anthony Liguori

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  hw/qdev-properties.h |  130 
 ++
  hw/qdev.h|  126 +---
  2 files changed, 131 insertions(+), 125 deletions(-)
  create mode 100644 hw/qdev-properties.h

 diff --git a/hw/qdev-properties.h b/hw/qdev-properties.h
 new file mode 100644
 index 000..329ef70
 --- /dev/null
 +++ b/hw/qdev-properties.h
 @@ -0,0 +1,130 @@
 +#ifndef QDEV_PROPERTIES_H
 +#define QDEV_PROPERTIES_H
 +
 +#include qemu/object.h
 +#include qemu-queue.h
 +
 +typedef struct Property Property;
 +
 +typedef struct PropertyInfo PropertyInfo;
 +
 +struct Property {
 +const char   *name;
 +PropertyInfo *info;
 +int  offset;
 +uint8_t  bitnr;
 +uint8_t  qtype;
 +int64_t  defval;
 +};
 +
 +struct PropertyInfo {
 +const char *name;
 +const char *legacy_name;
 +const char **enum_table;
 +int (*parse)(DeviceState *dev, Property *prop, const char *str);
 +int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
 +ObjectPropertyAccessor *get;
 +ObjectPropertyAccessor *set;
 +ObjectPropertyRelease *release;
 +};
 +
 +typedef struct GlobalProperty {
 +const char *driver;
 +const char *property;
 +const char *value;
 +QTAILQ_ENTRY(GlobalProperty) next;
 +} GlobalProperty;
 +
 +extern PropertyInfo qdev_prop_bit;
 +extern PropertyInfo qdev_prop_uint8;
 +extern PropertyInfo qdev_prop_uint16;
 +extern PropertyInfo qdev_prop_uint32;
 +extern PropertyInfo qdev_prop_int32;
 +extern PropertyInfo qdev_prop_uint64;
 +extern PropertyInfo qdev_prop_hex8;
 +extern PropertyInfo qdev_prop_hex32;
 +extern PropertyInfo qdev_prop_hex64;
 +extern PropertyInfo qdev_prop_string;
 +extern PropertyInfo qdev_prop_chr;
 +extern PropertyInfo qdev_prop_ptr;
 +extern PropertyInfo qdev_prop_macaddr;
 +extern PropertyInfo qdev_prop_losttickpolicy;
 +extern PropertyInfo qdev_prop_bios_chs_trans;
 +extern PropertyInfo qdev_prop_drive;
 +extern PropertyInfo qdev_prop_netdev;
 +extern PropertyInfo qdev_prop_vlan;
 +extern PropertyInfo qdev_prop_pci_devfn;
 +extern PropertyInfo qdev_prop_blocksize;
 +extern PropertyInfo qdev_prop_pci_host_devaddr;
 +
 +#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
 +.name  = (_name),\
 +.info  = (_prop),   \
 +.offset= offsetof(_state, _field)\
 ++ type_check(_type,typeof_field(_state, _field)),\
 +}
 +#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
 +.name  = (_name),   \
 +.info  = (_prop),  \
 +.offset= offsetof(_state, _field)   \
 ++ type_check(_type,typeof_field(_state, _field)),   \
 +.qtype = QTYPE_QINT,\
 +.defval= (_type)_defval,\
 +}
 +#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) {  \
 +.name  = (_name),\
 +.info  = (qdev_prop_bit),   \
 +.bitnr= (_bit),  \
 +.offset= offsetof(_state, _field)\
 ++ type_check(uint32_t,typeof_field(_state, _field)), \
 +.qtype = QTYPE_QBOOL,\
 +.defval= (bool)_defval,  \
 +}
 +
 +#define DEFINE_PROP_UINT8(_n, _s, _f, _d)   \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
 +#define DEFINE_PROP_UINT16(_n, _s, _f, _d)  \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
 +#define DEFINE_PROP_UINT32(_n, _s, _f, _d)  \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
 +#define DEFINE_PROP_INT32(_n, _s, _f, _d)  \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
 +#define DEFINE_PROP_UINT64(_n, _s, _f, _d)  \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
 +#define DEFINE_PROP_HEX8(_n, _s, _f, _d)   \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
 +#define DEFINE_PROP_HEX32(_n, _s, _f, _d)   \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
 +#define DEFINE_PROP_HEX64(_n, _s, _f, _d)   \
 +DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
 +#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d)   \
 +  

Re: [Qemu-devel] [PATCH 10/22] qapi: qapi.py, make json parser more robust

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

 Currently the QAPI JSON parser expects a very particular style of code
 indentation, the major one being that terminating curly/square brackets are
 not on placed on a seperate line. This is incompatible with most
 pretty-print formats, so make it a little more robust by supporting
 these cases.

The code was supposed to just expect that all subsequent lines are
indented.  This was to simplify the parser.  Can you provide an
problematic example?

Regards,

Anthony Liguori
[...]




Re: [Qemu-devel] [PATCH 11/22] qapi: add open-coded visitor for struct tm types

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  qapi/Makefile.objs |1 +
  qapi/misc-qapi-visit.c |   14 ++
  qapi/qapi-visit-core.h |3 +++
  3 files changed, 18 insertions(+)
  create mode 100644 qapi/misc-qapi-visit.c

 diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
 index 5f5846e..7604b52 100644
 --- a/qapi/Makefile.objs
 +++ b/qapi/Makefile.objs
 @@ -1,3 +1,4 @@
  qapi-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o
  qapi-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o
  qapi-obj-y += string-input-visitor.o string-output-visitor.o opts-visitor.o
 +qapi-obj-y += misc-qapi-visit.o
 diff --git a/qapi/misc-qapi-visit.c b/qapi/misc-qapi-visit.c
 new file mode 100644
 index 000..a44773d
 --- /dev/null
 +++ b/qapi/misc-qapi-visit.c
 @@ -0,0 +1,14 @@
 +#include time.h
 +#include qidl.h
 +
 +void visit_type_tm(Visitor *v, struct tm *obj, const char *name, Error 
 **errp)
 +{
 +visit_start_struct(v, NULL, struct tm, name, 0, errp);
 +visit_type_int32(v, obj-tm_year, tm_year, errp);
 +visit_type_int32(v, obj-tm_mon, tm_mon, errp);
 +visit_type_int32(v, obj-tm_mday, tm_mday, errp);
 +visit_type_int32(v, obj-tm_hour, tm_hour, errp);
 +visit_type_int32(v, obj-tm_min, tm_min, errp);
 +visit_type_int32(v, obj-tm_sec, tm_sec, errp);
 +visit_end_struct(v, errp);
 +}
 diff --git a/qapi/qapi-visit-core.h b/qapi/qapi-visit-core.h
 index 4a7bdb6..6af9f5e 100644
 --- a/qapi/qapi-visit-core.h
 +++ b/qapi/qapi-visit-core.h
 @@ -100,4 +100,7 @@ void visit_start_array(Visitor *v, void **obj, const char 
 *name,
  void visit_next_array(Visitor *v, Error **errp);
  void visit_end_array(Visitor *v, Error **errp);
  
 +/* misc. visitors */
 +void visit_type_tm(Visitor *m, struct tm *obj, const char *name, Error 
 **errp);
 +
  #endif
 -- 
 1.7.9.5




[Qemu-devel] [RFC 8/9] virtio-scsi: Set max_target=0 during vhost-scsi operation

2012-07-24 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This QEMU patch sets VirtIOSCSIConfig-max_target=0 for vhost-scsi operation
to restrict virtio-scsi LLD guest scanning to max_id=0 (a single target ID
instance) when connected to individual tcm_vhost endpoints.

This ensures that virtio-scsi LLD only attempts to scan target IDs up to
VIRTIO_SCSI_MAX_TARGET when connected via virtio-scsi-raw.

Cc: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Cc: Zhi Yong Wu wu...@linux.vnet.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/virtio-scsi.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index b0adfde..d854998 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -534,7 +534,11 @@ static void virtio_scsi_get_config(VirtIODevice *vdev,
 stl_raw(scsiconf-sense_size, s-sense_size);
 stl_raw(scsiconf-cdb_size, s-cdb_size);
 stl_raw(scsiconf-max_channel, VIRTIO_SCSI_MAX_CHANNEL);
-stl_raw(scsiconf-max_target, VIRTIO_SCSI_MAX_TARGET);
+if (s-vhost_scsi) {
+stl_raw(scsiconf-max_target, 0);
+} else {
+stl_raw(scsiconf-max_target, VIRTIO_SCSI_MAX_TARGET);
+}
 stl_raw(scsiconf-max_lun, VIRTIO_SCSI_MAX_LUN);
 }
 
-- 
1.7.2.5




[Qemu-devel] [RFC 9/9] vhost-scsi: add -vhost-scsi host device

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

This patch adds a new type of host device that drives the vhost_scsi
device.  The syntax to add vhost-scsi is:

  qemu -vhost-scsi id=vhost-scsi0,wwpn=...,tpgt=123

The virtio-scsi emulated device will make use of vhost-scsi to process
virtio-scsi requests inside the kernel and hand them to the in-kernel
SCSI target stack.

Changelog v0 - v1:

- Add VHOST_SCSI_SET_ENDPOINT call (stefan)
- Enable vhost notifiers for multiple queues (Zhi)
- clear vhost-scsi endpoint on stopped (Zhi)
- Add CONFIG_VHOST_SCSI for QEMU build configure (nab)
- Rename vhost_vring_target - vhost_scsi_target (mst + nab)
- Add support for VHOST_SCSI_GET_ABI_VERSION ioctl (aliguori + nab)

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
Cc: Anthony Liguori aligu...@us.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Cc: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 configure|   10 +++
 hw/Makefile.objs |1 +
 hw/qdev-properties.c |   32 +
 hw/qdev.h|3 +
 hw/vhost-scsi.c  |  173 ++
 hw/vhost-scsi.h  |   50 ++
 qemu-common.h|1 +
 qemu-config.c|   16 +
 qemu-options.hx  |4 +
 vl.c |   18 +
 10 files changed, 308 insertions(+), 0 deletions(-)
 create mode 100644 hw/vhost-scsi.c
 create mode 100644 hw/vhost-scsi.h

diff --git a/configure b/configure
index cef0a71..2291e7e 100755
--- a/configure
+++ b/configure
@@ -144,6 +144,7 @@ libattr=
 xfs=
 
 vhost_net=no
+vhost_scsi=no
 kvm=no
 gprof=no
 debug_tcg=no
@@ -489,6 +490,7 @@ Haiku)
   usb=linux
   kvm=yes
   vhost_net=yes
+  vhost_scsi=yes
   if [ $cpu = i386 -o $cpu = x86_64 ] ; then
 audio_possible_drivers=$audio_possible_drivers fmod
   fi
@@ -794,6 +796,10 @@ for opt do
   ;;
   --enable-vhost-net) vhost_net=yes
   ;;
+  --disable-vhost-net) vhost_scsi=no
+  ;;
+  --enable-vhost-net) vhost_scsi=yes
+  ;;
   --disable-opengl) opengl=no
   ;;
   --enable-opengl) opengl=yes
@@ -3059,6 +3065,7 @@ echo posix_madvise $posix_madvise
 echo uuid support  $uuid
 echo libcap-ng support $cap_ng
 echo vhost-net support $vhost_net
+echo vhost-scsi support $vhost_scsi
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
@@ -3762,6 +3769,9 @@ case $target_arch2 in
   if test $vhost_net = yes ; then
 echo CONFIG_VHOST_NET=y  $config_target_mak
   fi
+  if test $vhost_scsi = yes ; then
+echo CONFIG_VHOST_SCSI=y  $config_target_mak
+  fi
 fi
 esac
 case $target_arch2 in
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 8327e55..37a0d0e 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -161,6 +161,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o 
virtio-balloon.o virtio-net.o
 obj-$(CONFIG_VIRTIO) += virtio-serial-bus.o virtio-scsi.o
 obj-$(CONFIG_SOFTMMU) += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
+obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/
 obj-$(CONFIG_NO_PCI) += pci-stub.o
 obj-$(CONFIG_VGA) += vga.o
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 24b39e8..0c538d2 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -3,6 +3,7 @@
 #include qerror.h
 #include blockdev.h
 #include hw/block-common.h
+#include vhost-scsi.h
 
 void *qdev_get_prop_ptr(DeviceState *dev, Property *prop)
 {
@@ -685,6 +686,37 @@ PropertyInfo qdev_prop_vlan = {
 .set   = set_vlan,
 };
 
+/* --- vhost-scsi --- */
+
+static int parse_vhost_scsi(DeviceState *dev, Property *prop, const char *str)
+{
+VHostSCSI **ptr = qdev_get_prop_ptr(dev, prop);
+
+*ptr = find_vhost_scsi(str);
+if (*ptr == NULL) {
+return -ENOENT;
+}
+return 0;
+}
+
+static int print_vhost_scsi(DeviceState *dev, Property *prop,
+char *dest, size_t len)
+{
+VHostSCSI **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+return snprintf(dest, len, %s, vhost_scsi_get_id(*ptr));
+} else {
+return snprintf(dest, len, null);
+}
+}
+
+PropertyInfo qdev_prop_vhost_scsi = {
+.name  = vhost-scsi,
+.parse = parse_vhost_scsi,
+.print = print_vhost_scsi,
+};
+
 /* --- pointer --- */
 
 /* Not a proper property, just for dirty hacks.  TODO Remove it!  */
diff --git a/hw/qdev.h b/hw/qdev.h
index a2cbd9d..ddc0791 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -238,6 +238,7 @@ extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
 extern PropertyInfo qdev_prop_blocksize;
 extern PropertyInfo qdev_prop_pci_host_devaddr;
+extern PropertyInfo qdev_prop_vhost_scsi;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
 .name  = (_name),\
@@ -305,6 +306,8 @@ extern PropertyInfo qdev_prop_pci_host_devaddr;
 

[Qemu-devel] [RFC 5/9] virtio-scsi: Add wwpn and tgpt properties

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

A vhost-scsi device must be bound to a tcm_vhost target port.  This will
be done by issuing an ioctl to the device with the wwpn and tgpt.  This
patch adds these properties to the virtio-scsi-pci device:

  qemu -device virtio-scsi-pci,wwpn=$TARGET_WWN,tgpt=$TPGT

Future patches will open /dev/vhost-scsi and issue the ioctl.

This patch also moves the virtio_scsi_init() prototype to
hw/virtio-scsi.h where the VirtIOSCSIConf structure is defined.  I think
this is cleaner than defining it in hw/virtio.h.

(v2: Use modern VirtIOSCSIConf define in virtio-scsi.h)

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Cc: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/virtio-scsi.c |2 ++
 hw/virtio-scsi.h |1 +
 2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 0a5ac40..4a787d3 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -13,6 +13,8 @@
  *
  */
 
+#include qemu-common.h
+#include qemu-error.h
 #include virtio-scsi.h
 #include hw/scsi.h
 #include hw/scsi-defs.h
diff --git a/hw/virtio-scsi.h b/hw/virtio-scsi.h
index 4bc889d..74e9422 100644
--- a/hw/virtio-scsi.h
+++ b/hw/virtio-scsi.h
@@ -22,6 +22,7 @@
 #define VIRTIO_ID_SCSI  8
 
 struct VirtIOSCSIConf {
+VHostSCSI *vhost_scsi;
 uint32_t num_queues;
 uint32_t max_sectors;
 uint32_t cmd_per_lun;
-- 
1.7.2.5




Re: [Qemu-devel] [PATCH 10/22] qapi: qapi.py, make json parser more robust

2012-07-24 Thread Michael Roth
On Tue, Jul 24, 2012 at 05:23:33PM -0500, Anthony Liguori wrote:
 Michael Roth mdr...@linux.vnet.ibm.com writes:
 
  Currently the QAPI JSON parser expects a very particular style of code
  indentation, the major one being that terminating curly/square brackets are
  not on placed on a seperate line. This is incompatible with most
  pretty-print formats, so make it a little more robust by supporting
  these cases.
 
 The code was supposed to just expect that all subsequent lines are
 indented.  This was to simplify the parser.  Can you provide an
 problematic example?

The main one was cases like this:

mdroth@loki:~/w/qemu3.git$ cat example.json 
{
'a': 'test'
}
mdroth@loki:~/w/qemu3.git$ python scripts/qapi-types.py -o /tmp 
example.json 
Traceback (most recent call last):
  File scripts/qapi-types.py, line 260, in module
exprs = parse_schema(sys.stdin)
  File /home/mdroth/dev/kvm/qemu3.git/scripts/qapi.py, line 76, in 
parse_schema
expr_eval = evaluate(expr)
  File /home/mdroth/dev/kvm/qemu3.git/scripts/qapi.py, line 62, in 
evaluate
return parse(map(lambda x: x, tokenize(string)))[0]
  File /home/mdroth/dev/kvm/qemu3.git/scripts/qapi.py, line 42, in parse
if tokens[0] == ',':
IndexError: list index out of range

I had it in my queue because it was what was preventing me from pretty-printing
the QIDL-generated schemas in V1, since python's pretty print stuff generally
puts the opening/closing braces at the same indent level. But now we store them
in the binary, and don't pretty-print those, so I don't think this is an issue
WRT this series anymore. Might still make sense to add it for future use-cases
though.

 
 Regards,
 
 Anthony Liguori
 [...]
 



[Qemu-devel] [RFC 0/9] vhost-scsi: Add support for host virtualized target

2012-07-24 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

Hi Anthony + QEMU storage folks,

The following is a reviewable RFC series of vhost-scsi against yesterday's
QEMU.git/master @ commit 401a66357d.

The series is available directly from:

  git://git.kernel.org/pub/scm/virt/kvm/nab/qemu-kvm.git vhost-scsi-merge

It contains the squashed + re-ordered patches from Stefan - Zhi's QEMU
original work into a updated series against recent QEMU code.

As mentioned recently on qemu-devel here:

  http://lists.gnu.org/archive/html/qemu-devel/2012-07/msg03280.html

the 'vhost-scsi-merge' branch is currently failing with vhost/virtio
errors using the latest HEAD.  Stefan + myself are currently working through
the 1.1.0 regressions, and will be posting incremental patches against this
working tree as individual progress is made..

Please have a look.

--nab

P.S:

Also, for folks who are interested in trying out a working virtio-scsi - 
tcm_vhost
setup, check out using branch 'vhost-scsi' with the last pre-regression
commit from upstream QEMU that appears to be performing very well.

This along with target-pending.git/for-next-merge for KVM host + a virtio-scsi
SCSI LLD bugfix for KVM guest that's headed into 3.6-rc1 here should be enough
to get up and running:

virtio-scsi: Add vdrv-scan for post VIRTIO_CONFIG_S_DRIVER_OK LUN scanning
http://git.kernel.org/?p=linux/kernel/git/jejb/scsi.git;a=commitdiff;h=59057fbc37178f10a196ab7ec170b80273f75a47;hp=0b1017aab197271a78169fde3d7e487bb721997c

Thanks!

Nicholas Bellinger (1):
  virtio-scsi: Set max_target=0 during vhost-scsi operation

Stefan Hajnoczi (8):
  notifier: add validity check and notify function
  virtio-pci: support host notifiers in TCG mode
  virtio-pci: check that event notification worked
  vhost: Pass device path to vhost_dev_init()
  virtio-scsi: Add wwpn and tgpt properties
  virtio-scsi: Open and initialize /dev/vhost-scsi
  virtio-scsi: Start/stop vhost
  vhost-scsi: add -vhost-scsi host device

 configure|   10 +++
 event_notifier.c |   21 ++
 event_notifier.h |4 +
 hw/Makefile.objs |1 +
 hw/qdev-properties.c |   32 +
 hw/qdev.h|3 +
 hw/vhost-scsi.c  |  173 ++
 hw/vhost-scsi.h  |   50 ++
 hw/vhost.c   |5 +-
 hw/vhost.h   |3 +-
 hw/vhost_net.c   |2 +-
 hw/virtio-pci.c  |   28 +++-
 hw/virtio-scsi.c |   59 +-
 hw/virtio-scsi.h |1 +
 hw/virtio.c  |7 ++
 qemu-common.h|1 +
 qemu-config.c|   16 +
 qemu-options.hx  |4 +
 vl.c |   18 +
 19 files changed, 430 insertions(+), 8 deletions(-)
 create mode 100644 hw/vhost-scsi.c
 create mode 100644 hw/vhost-scsi.h

-- 
1.7.2.5




[Qemu-devel] [RFC 3/9] virtio-pci: check that event notification worked

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

For sanity assert that event notification succeeds.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Cc: Anthony Liguori aligu...@us.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/virtio-pci.c |5 -
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 538eef4..0f0f766 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -261,8 +261,11 @@ static void virtio_pci_queue_notify(VirtIOPCIProxy *proxy, 
uint32_t n)
 vq = virtio_get_queue(proxy-vdev, n);
 notifier = virtio_queue_get_host_notifier(vq);
 if (event_notifier_valid(notifier)) {
+int r;
+
 printf(notifying vq %u host notifier from userspace\n, n);
-event_notifier_notify(notifier);
+r = event_notifier_notify(notifier);
+assert(r == 0);
 } else {
 virtio_queue_notify_vq(vq);
 }
-- 
1.7.2.5




[Qemu-devel] [RFC 1/9] notifier: add validity check and notify function

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

Event notifiers that have not had the event_notifier_init() function
called on them are invalid.  The event_notifier_valid() function checks
whether or not an event notifier is valild.  This can be used to check
whether a notifier is in use or not.

It sometimes useful to notify the event notifier, for example when vhost
is on the receiving end of the event notifier and qemu needs to notify
it.  The event_notifier_notify() function will signal the eventfd and
increment it by one.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Cc: Anthony Liguori aligu...@us.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 event_notifier.c |   21 +
 event_notifier.h |4 
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/event_notifier.c b/event_notifier.c
index 2c207e1..efe00ea 100644
--- a/event_notifier.c
+++ b/event_notifier.c
@@ -25,6 +25,7 @@ void event_notifier_init_fd(EventNotifier *e, int fd)
 
 int event_notifier_init(EventNotifier *e, int active)
 {
+assert(!event_notifier_valid(e));
 #ifdef CONFIG_EVENTFD
 int fd = eventfd(!!active, EFD_NONBLOCK | EFD_CLOEXEC);
 if (fd  0)
@@ -39,6 +40,12 @@ int event_notifier_init(EventNotifier *e, int active)
 void event_notifier_cleanup(EventNotifier *e)
 {
 close(e-fd);
+e-fd = -1;
+}
+
+bool event_notifier_valid(EventNotifier *e)
+{
+return e-fd != -1;
 }
 
 int event_notifier_get_fd(EventNotifier *e)
@@ -65,3 +72,17 @@ int event_notifier_test_and_clear(EventNotifier *e)
 int r = read(e-fd, value, sizeof(value));
 return r == sizeof(value);
 }
+
+int event_notifier_notify(EventNotifier *e)
+{
+uint64_t value = 1;
+int r;
+
+assert(event_notifier_valid(e));
+r = write(e-fd, value, sizeof(value));
+if (r  0) {
+return -errno;
+}
+assert(r == sizeof(value));
+return 0;
+}
diff --git a/event_notifier.h b/event_notifier.h
index f0ec2f2..eea10a9 100644
--- a/event_notifier.h
+++ b/event_notifier.h
@@ -15,6 +15,8 @@
 
 #include qemu-common.h
 
+#define EVENT_NOTIFIER_INITIALIZER ((EventNotifier){ .fd = -1 })
+
 struct EventNotifier {
 int fd;
 };
@@ -24,9 +26,11 @@ typedef void EventNotifierHandler(EventNotifier *);
 void event_notifier_init_fd(EventNotifier *, int fd);
 int event_notifier_init(EventNotifier *, int active);
 void event_notifier_cleanup(EventNotifier *);
+bool event_notifier_valid(EventNotifier *e);
 int event_notifier_get_fd(EventNotifier *);
 int event_notifier_set(EventNotifier *);
 int event_notifier_test_and_clear(EventNotifier *);
 int event_notifier_set_handler(EventNotifier *, EventNotifierHandler *);
+int event_notifier_notify(EventNotifier *e);
 
 #endif
-- 
1.7.2.5




[Qemu-devel] [RFC 2/9] virtio-pci: support host notifiers in TCG mode

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

Normally host notifiers are only used together with vhost-net in KVM
mode.  It is occassionally useful to use vhost with TCG mode, mainly for
testing and development.  This isn't hard to achieve, simply fall back
to notifying the host notifier manually from qemu if KVM mode is
disabled.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Cc: Anthony Liguori aligu...@us.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/virtio-pci.c |   23 ---
 hw/virtio.c |7 +++
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 4e03f0b..538eef4 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -249,6 +249,25 @@ void virtio_pci_reset(DeviceState *d)
 proxy-flags = ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
 }
 
+static void virtio_pci_queue_notify(VirtIOPCIProxy *proxy, uint32_t n)
+{
+VirtQueue *vq;
+EventNotifier *notifier;
+
+if (n = VIRTIO_PCI_QUEUE_MAX) {
+return;
+}
+
+vq = virtio_get_queue(proxy-vdev, n);
+notifier = virtio_queue_get_host_notifier(vq);
+if (event_notifier_valid(notifier)) {
+printf(notifying vq %u host notifier from userspace\n, n);
+event_notifier_notify(notifier);
+} else {
+virtio_queue_notify_vq(vq);
+}
+}
+
 static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
 VirtIOPCIProxy *proxy = opaque;
@@ -278,9 +297,7 @@ static void virtio_ioport_write(void *opaque, uint32_t 
addr, uint32_t val)
 vdev-queue_sel = val;
 break;
 case VIRTIO_PCI_QUEUE_NOTIFY:
-if (val  VIRTIO_PCI_QUEUE_MAX) {
-virtio_queue_notify(vdev, val);
-}
+virtio_pci_queue_notify(proxy, val);
 break;
 case VIRTIO_PCI_STATUS:
 if (!(val  VIRTIO_CONFIG_S_DRIVER_OK)) {
diff --git a/hw/virtio.c b/hw/virtio.c
index d146f86..36a18b5 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -536,6 +536,11 @@ void virtio_reset(void *opaque)
 vdev-vq[i].signalled_used = 0;
 vdev-vq[i].signalled_used_valid = false;
 vdev-vq[i].notification = true;
+
+assert(!event_notifier_valid(vdev-vq[i].guest_notifier));
+assert(!event_notifier_valid(vdev-vq[i].host_notifier));
+vdev-vq[i].guest_notifier = EVENT_NOTIFIER_INITIALIZER;
+vdev-vq[i].host_notifier = EVENT_NOTIFIER_INITIALIZER;
 }
 }
 
@@ -905,6 +910,8 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t 
device_id,
 for(i = 0; i  VIRTIO_PCI_QUEUE_MAX; i++) {
 vdev-vq[i].vector = VIRTIO_NO_VECTOR;
 vdev-vq[i].vdev = vdev;
+vdev-vq[i].guest_notifier = EVENT_NOTIFIER_INITIALIZER;
+vdev-vq[i].host_notifier = EVENT_NOTIFIER_INITIALIZER;
 }
 
 vdev-name = name;
-- 
1.7.2.5




[Qemu-devel] [RFC 7/9] virtio-scsi: Start/stop vhost

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

This patch starts and stops vhost as the virtio device transitions
through its status phases.  Vhost can only be started once the guest
reports its driver has successfully initialized, which means the
virtqueues have been set up by the guest.

(v2: Squash virtio-scsi: use the vhost-scsi host device from stefan)

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
Cc: Michael S. Tsirkin m...@redhat.com
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/virtio-pci.c  |2 ++
 hw/virtio-scsi.c |   41 -
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 0f0f766..64f2f0d 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -1060,6 +1060,8 @@ static int virtio_scsi_exit_pci(PCIDevice *pci_dev)
 }
 
 static Property virtio_scsi_properties[] = {
+DEFINE_PROP_VHOST_SCSI(vhost-scsi, VirtIOPCIProxy,
+scsi.vhost_scsi),
 DEFINE_PROP_UINT32(vectors, VirtIOPCIProxy, nvectors, 2),
 DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOPCIProxy, host_features, scsi),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index dea3269..b0adfde 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -15,6 +15,7 @@
 
 #include qemu-common.h
 #include qemu-error.h
+#include vhost-scsi.h
 #include virtio-scsi.h
 #include hw/scsi.h
 #include hw/scsi-defs.h
@@ -601,6 +602,38 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
 .load_request = virtio_scsi_load_request,
 };
 
+static bool virtio_scsi_started(VirtIOSCSI *s, uint8_t val)
+{
+return (val  VIRTIO_CONFIG_S_DRIVER_OK)  s-vdev.vm_running;
+}
+
+static void virtio_scsi_set_status(VirtIODevice *vdev, uint8_t val)
+{
+VirtIOSCSI *s = to_virtio_scsi(vdev);
+bool start = virtio_scsi_started(s, val);
+
+if (s-vhost_started == start) {
+return;
+}
+
+if (start) {
+int ret;
+
+ret = vhost_scsi_start(s-vhost_scsi, vdev);
+if (ret  0) {
+error_report(virtio-scsi: unable to start vhost: %s\n,
+ strerror(-ret));
+
+/* There is no userspace virtio-scsi fallback so exit */
+exit(1);
+}
+} else {
+vhost_scsi_stop(s-vhost_scsi, vdev);
+}
+
+s-vhost_started = start;
+}
+
 VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)
 {
 VirtIOSCSI *s;
@@ -622,6 +655,9 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, 
VirtIOSCSIConf *proxyconf)
 s-vdev.set_config = virtio_scsi_set_config;
 s-vdev.get_features = virtio_scsi_get_features;
 s-vdev.reset = virtio_scsi_reset;
+if (s-vhost_scsi) {
+s-vdev.set_status = virtio_scsi_set_status;
+}
 
 s-ctrl_vq = virtio_add_queue(s-vdev, VIRTIO_SCSI_VQ_SIZE,
virtio_scsi_handle_ctrl);
@@ -647,6 +683,9 @@ void virtio_scsi_exit(VirtIODevice *vdev)
 {
 VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 unregister_savevm(s-qdev, virtio-scsi, s);
-vhost_dev_cleanup(s-vhost_scsi);
+
+/* This will stop vhost backend if appropriate. */
+virtio_scsi_set_status(vdev, 0);
+
 virtio_cleanup(vdev);
 }
-- 
1.7.2.5




[Qemu-devel] [RFC 6/9] virtio-scsi: Open and initialize /dev/vhost-scsi

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

Begin adding vhost support by opening /dev/vhost-scsi.

(v2: Drop legacy -vhost_vqs[] usage)

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Signed-off-by: Zhi Yong Wu wu...@linux.vnet.ibm.com
Cc: Michael S. Tsirkin m...@redhat.com
Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/virtio-scsi.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 4a787d3..dea3269 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -18,6 +18,7 @@
 #include virtio-scsi.h
 #include hw/scsi.h
 #include hw/scsi-defs.h
+#include vhost.h
 
 #define VIRTIO_SCSI_VQ_SIZE 128
 #define VIRTIO_SCSI_CDB_SIZE32
@@ -137,6 +138,9 @@ typedef struct {
 VirtQueue *ctrl_vq;
 VirtQueue *event_vq;
 VirtQueue *cmd_vqs[0];
+
+bool vhost_started;
+VHostSCSI *vhost_scsi;
 } VirtIOSCSI;
 
 typedef struct VirtIOSCSIReq {
@@ -456,6 +460,11 @@ static void virtio_scsi_fail_cmd_req(VirtIOSCSIReq *req)
 virtio_scsi_complete_req(req);
 }
 
+static VirtIOSCSI *to_virtio_scsi(VirtIODevice *vdev)
+{
+return (VirtIOSCSI *)vdev;
+}
+
 static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq)
 {
 VirtIOSCSI *s = (VirtIOSCSI *)vdev;
@@ -605,6 +614,8 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, 
VirtIOSCSIConf *proxyconf)
 
 s-qdev = dev;
 s-conf = proxyconf;
+s-vhost_started = false;
+s-vhost_scsi = proxyconf-vhost_scsi;
 
 /* TODO set up vdev function pointers */
 s-vdev.get_config = virtio_scsi_get_config;
@@ -636,5 +647,6 @@ void virtio_scsi_exit(VirtIODevice *vdev)
 {
 VirtIOSCSI *s = (VirtIOSCSI *)vdev;
 unregister_savevm(s-qdev, virtio-scsi, s);
+vhost_dev_cleanup(s-vhost_scsi);
 virtio_cleanup(vdev);
 }
-- 
1.7.2.5




[Qemu-devel] [RFC 4/9] vhost: Pass device path to vhost_dev_init()

2012-07-24 Thread Nicholas A. Bellinger
From: Stefan Hajnoczi stefa...@linux.vnet.ibm.com

The path to /dev/vhost-net is currently hardcoded in vhost_dev_init().
This needs to be changed so that /dev/vhost-scsi can be used.  Pass in
the device path instead of hardcoding it.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
Cc: Paolo Bonzini pbonz...@redhat.com
Cc: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 hw/vhost.c |5 +++--
 hw/vhost.h |3 ++-
 hw/vhost_net.c |2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/vhost.c b/hw/vhost.c
index 0fd8da8..d0ce5aa 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -747,14 +747,15 @@ static void vhost_eventfd_del(MemoryListener *listener,
 {
 }
 
-int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
+int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
+   bool force)
 {
 uint64_t features;
 int r;
 if (devfd = 0) {
 hdev-control = devfd;
 } else {
-hdev-control = open(/dev/vhost-net, O_RDWR);
+hdev-control = open(devpath, O_RDWR);
 if (hdev-control  0) {
 return -errno;
 }
diff --git a/hw/vhost.h b/hw/vhost.h
index 80e64df..0c47229 100644
--- a/hw/vhost.h
+++ b/hw/vhost.h
@@ -44,7 +44,8 @@ struct vhost_dev {
 bool force;
 };
 
-int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force);
+int vhost_dev_init(struct vhost_dev *hdev, int devfd, const char *devpath,
+   bool force);
 void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index 75f8211..9faadfd 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -109,7 +109,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, 
int devfd,
 (1  VHOST_NET_F_VIRTIO_NET_HDR);
 net-backend = r;
 
-r = vhost_dev_init(net-dev, devfd, force);
+r = vhost_dev_init(net-dev, devfd, /dev/vhost-net, force);
 if (r  0) {
 goto fail;
 }
-- 
1.7.2.5




Re: [Qemu-devel] [PATCH 01/22] qapi: qapi-visit.py - qapi_visit.py so we can import

2012-07-24 Thread Anthony Liguori
Michael Roth mdr...@linux.vnet.ibm.com writes:

Reviewed-by: Anthony Liguori aligu...@us.ibm.com

Regards,

Anthony Liguori


 Python doesn't allow - in module names, so we need to rename the file
 so we can re-use bits of the codegen

 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  Makefile  |4 +-
  scripts/qapi-visit.py |  352 
 -
  scripts/qapi_visit.py |  352 
 +
  tests/Makefile|4 +-
  4 files changed, 356 insertions(+), 356 deletions(-)
  delete mode 100644 scripts/qapi-visit.py
  create mode 100644 scripts/qapi_visit.py

 diff --git a/Makefile b/Makefile
 index ab82ef3..ea7174c 100644
 --- a/Makefile
 +++ b/Makefile
 @@ -195,8 +195,8 @@ qapi-types.c qapi-types.h :\
  $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py
   $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py 
 $(gen-out-type) -o .  $,   GEN   $@)
  qapi-visit.c qapi-visit.h :\
 -$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py
 - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py 
 $(gen-out-type) -o .   $,   GEN   $@)
 +$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi_visit.py
 + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi_visit.py 
 $(gen-out-type) -o .   $,   GEN   $@)
  qmp-commands.h qmp-marshal.c :\
  $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py
   $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py 
 $(gen-out-type) -m -o .  $,   GEN   $@)
 diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
 deleted file mode 100644
 index 04ef7c4..000
 --- a/scripts/qapi-visit.py
 +++ /dev/null
 @@ -1,352 +0,0 @@
 -#
 -# QAPI visitor generator
 -#
 -# Copyright IBM, Corp. 2011
 -#
 -# Authors:
 -#  Anthony Liguori aligu...@us.ibm.com
 -#  Michael Rothmdr...@linux.vnet.ibm.com
 -#
 -# This work is licensed under the terms of the GNU GPLv2.
 -# See the COPYING.LIB file in the top-level directory.
 -
 -from ordereddict import OrderedDict
 -from qapi import *
 -import sys
 -import os
 -import getopt
 -import errno
 -
 -def generate_visit_struct_body(field_prefix, name, members):
 -ret = mcgen('''
 -if (!error_is_set(errp)) {
 -''')
 -push_indent()
 -
 -if len(field_prefix):
 -field_prefix = field_prefix + .
 -ret += mcgen('''
 -Error **errp = err; /* from outer scope */
 -Error *err = NULL;
 -visit_start_struct(m, NULL, , %(name)s, 0, err);
 -''',
 -name=name)
 -else:
 -ret += mcgen('''
 -Error *err = NULL;
 -visit_start_struct(m, (void **)obj, %(name)s, name, sizeof(%(name)s), 
 err);
 -''',
 -name=name)
 -
 -ret += mcgen('''
 -if (!err) {
 -if (!obj || *obj) {
 -''')
 -
 -push_indent()
 -push_indent()
 -for argname, argentry, optional, structured in parse_args(members):
 -if optional:
 -ret += mcgen('''
 -visit_start_optional(m, obj ? (*obj)-%(c_prefix)shas_%(c_name)s : NULL, 
 %(name)s, err);
 -if (obj  (*obj)-%(prefix)shas_%(c_name)s) {
 -''',
 - c_prefix=c_var(field_prefix), prefix=field_prefix,
 - c_name=c_var(argname), name=argname)
 -push_indent()
 -
 -if structured:
 -ret += generate_visit_struct_body(field_prefix + argname, 
 argname, argentry)
 -else:
 -ret += mcgen('''
 -visit_type_%(type)s(m, obj ? (*obj)-%(c_prefix)s%(c_name)s : NULL, 
 %(name)s, err);
 -''',
 - c_prefix=c_var(field_prefix), prefix=field_prefix,
 - type=type_name(argentry), c_name=c_var(argname),
 - name=argname)
 -
 -if optional:
 -pop_indent()
 -ret += mcgen('''
 -}
 -visit_end_optional(m, err);
 -''')
 -
 -pop_indent()
 -ret += mcgen('''
 -
 -error_propagate(errp, err);
 -err = NULL;
 -}
 -''')
 -
 -pop_indent()
 -pop_indent()
 -ret += mcgen('''
 -/* Always call end_struct if start_struct succeeded.  */
 -visit_end_struct(m, err);
 -}
 -error_propagate(errp, err);
 -}
 -''')
 -return ret
 -
 -def generate_visit_struct(name, members):
 -ret = mcgen('''
 -
 -void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, 
 Error **errp)
 -{
 -''',
 -name=name)
 -
 -push_indent()
 -ret += generate_visit_struct_body(, name, members)
 -pop_indent()
 -
 -ret += mcgen('''
 -}
 -''')
 -return ret
 -
 -def generate_visit_list(name, members):
 -return mcgen('''
 -
 -void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char 
 *name, Error **errp)
 -{
 -GenericList *i, **prev = (GenericList **)obj;
 -Error *err = NULL;
 -
 -if (!error_is_set(errp)) {
 -visit_start_list(m, name, err);
 -if (!err) {
 -for (; (i = visit_next_list(m, prev, 

[Qemu-devel] [PATCH v2 0/2] assorted device path formatting cleanups

2012-07-24 Thread Laszlo Ersek
As long as two qualifies as assorted.

v1-v2:
- abandon original idea, allocate sufficient memory for OFW device path
  formatting [Markus]
- all bus formatters should rely on glib for dynamic allocation [Peter]

Tested with an OVMF debug patch that grabs and logs the bootorder fw_cfg
file:

  /pci@i0cf8/ide@1,1/drive@0/disk@0
  /pci@i0cf8/ide@1,1/drive@1/disk@0
  /pci@i0cf8/isa@1/fdc@03f0/floppy@0
  /pci@i0cf8/ethernet@3/ethernet-phy@0

Laszlo Ersek (2):
  accomodate OpenFirmware device paths in sufficient storage
  get_fw_dev_path() impls should allocate memory with glib functions

 hw/ide/qdev.c |2 +-
 hw/isa-bus.c  |2 +-
 hw/pci.c  |2 +-
 hw/qdev.c |   54 +++---
 hw/scsi-bus.c |2 +-
 hw/sysbus.c   |2 +-
 6 files changed, 48 insertions(+), 16 deletions(-)




[Qemu-devel] [PATCH v2 1/2] accomodate OpenFirmware device paths in sufficient storage

2012-07-24 Thread Laszlo Ersek

Signed-off-by: Laszlo Ersek ler...@redhat.com
---
 hw/qdev.c |   54 +++---
 1 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index af54467..59cc0c2 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -25,6 +25,8 @@
inherit from a particular bus (e.g. PCI or I2C) rather than
this API directly.  */
 
+#include stdarg.h
+
 #include net.h
 #include qdev.h
 #include sysemu.h
@@ -495,36 +497,66 @@ static char *bus_get_fw_dev_path(BusState *bus, 
DeviceState *dev)
 return NULL;
 }
 
+static int snprintf_helper(char *p, int size, int len, const char *format, ...)
+{
+char *target;
+int free_sz;
+va_list args;
+int ret;
+
+if (len  size) {
+target = p + len;
+free_sz = size - len;
+}
+else {
+target = NULL;
+free_sz = 0;
+}
+
+va_start(args, format);
+ret = vsnprintf(target, free_sz, format, args);
+va_end(args);
+
+assert(ret = 0);
+return ret;
+}
+
+
 static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
 {
-int l = 0;
+int len = 0;
 
 if (dev  dev-parent_bus) {
 char *d;
-l = qdev_get_fw_dev_path_helper(dev-parent_bus-parent, p, size);
+len = qdev_get_fw_dev_path_helper(dev-parent_bus-parent, p, size);
 d = bus_get_fw_dev_path(dev-parent_bus, dev);
 if (d) {
-l += snprintf(p + l, size - l, %s, d);
+len += snprintf_helper(p, size, len, %s, d);
 g_free(d);
 } else {
-l += snprintf(p + l, size - l, %s, 
object_get_typename(OBJECT(dev)));
+len += snprintf_helper(p, size, len, %s,
+   object_get_typename(OBJECT(dev)));
 }
 }
-l += snprintf(p + l , size - l, /);
+len += snprintf_helper(p, size, len, /);
 
-return l;
+return len;
 }
 
 char* qdev_get_fw_dev_path(DeviceState *dev)
 {
-char path[128];
-int l;
+int len, len2;
+char *path;
 
-l = qdev_get_fw_dev_path_helper(dev, path, 128);
+len = qdev_get_fw_dev_path_helper(dev, NULL, 0);
+path = g_malloc(len + 1);
 
-path[l-1] = '\0';
+len2 = qdev_get_fw_dev_path_helper(dev, path, len + 1);
+assert(len2 == len);
 
-return strdup(path);
+assert(len  0);
+path[len - 1] = '\0';
+return path;
 }
 
 char *qdev_get_dev_path(DeviceState *dev)
-- 
1.7.1





[Qemu-devel] [PATCH v2 2/2] get_fw_dev_path() impls should allocate memory with glib functions

2012-07-24 Thread Laszlo Ersek

Signed-off-by: Laszlo Ersek ler...@redhat.com
---
 hw/ide/qdev.c |2 +-
 hw/isa-bus.c  |2 +-
 hw/pci.c  |2 +-
 hw/scsi-bus.c |2 +-
 hw/sysbus.c   |2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 22e58df..4f15070 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -60,7 +60,7 @@ static char *idebus_get_fw_dev_path(DeviceState *dev)
 snprintf(path, sizeof(path), %s@%d, qdev_fw_name(dev),
  ((IDEBus*)dev-parent_bus)-bus_id);
 
-return strdup(path);
+return g_strdup(path);
 }
 
 static int ide_qdev_init(DeviceState *qdev)
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index f9b2373..47c93d3 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -236,7 +236,7 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
 snprintf(path + off, sizeof(path) - off, @%04x, d-ioport_id);
 }
 
-return strdup(path);
+return g_strdup(path);
 }
 
 MemoryRegion *isa_address_space(ISADevice *dev)
diff --git a/hw/pci.c b/hw/pci.c
index 99a4304..ef8996d 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1920,7 +1920,7 @@ static char *pcibus_get_fw_dev_path(DeviceState *dev)
PCI_SLOT(d-devfn));
 if (PCI_FUNC(d-devfn))
 snprintf(path + off, sizeof(path) + off, ,%x, PCI_FUNC(d-devfn));
-return strdup(path);
+return g_strdup(path);
 }
 
 static char *pcibus_get_dev_path(DeviceState *dev)
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index dc74063..4544d0b 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1547,7 +1547,7 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev)
 snprintf(path, sizeof(path), channel@%x/%s@%x,%x, d-channel,
  qdev_fw_name(dev), d-id, d-lun);
 
-return strdup(path);
+return g_strdup(path);
 }
 
 SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 9d8b1ea..c173840 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -211,7 +211,7 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
 snprintf(path + off, sizeof(path) - off, @i%04x, s-pio[0]);
 }
 
-return strdup(path);
+return g_strdup(path);
 }
 
 void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-- 
1.7.1




Re: [Qemu-devel] [PATCH 18/22] qidl: qidl.h

2012-07-24 Thread Michael Roth
On Tue, Jul 24, 2012 at 08:47:44PM +, Blue Swirl wrote:
 On Tue, Jul 24, 2012 at 5:20 PM, Michael Roth mdr...@linux.vnet.ibm.com 
 wrote:
 
  Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
  ---
   qidl.h |   58 ++
   1 file changed, 58 insertions(+)
   create mode 100644 qidl.h
 
  diff --git a/qidl.h b/qidl.h
  new file mode 100644
  index 000..75ae5af
  --- /dev/null
  +++ b/qidl.h
  @@ -0,0 +1,58 @@
  +/*
  + * QEMU IDL Macros/stubs
  + *
  + * See docs/qidl.txt for usage information.
  + *
  + * Copyright IBM, Corp. 2012
  + *
  + * Authors:
  + *  Michael Rothmdr...@linux.vnet.ibm.com
  + *
  + * This work is licensed under the terms of the GNU GPLv2.
 
 GPLv2 or later?
 

Yes, will fix.

  + * See the COPYING file in the top-level directory.
  + *
  + */
  +
  +#ifndef QIDL_H
  +#define QIDL_H
  +
  +#include qapi/qapi-visit-core.h
  +#include qemu/object.h
  +#include hw/qdev-properties.h
  +
  +#ifdef QIDL_GEN
  +
  +/* we pass the code through the preprocessor with QIDL_GEN defined to parse
  + * structures as they'd appear after preprocessing, and use the following
  + * definitions mostly to re-insert the initial macros/annotations so they
  + * stick around for the parser to process
 
 I guess this doesn't work if the file #includes itself, like some
 flash files used to do (or I can't find the example just now).
 

Yikes... I haven't encountered such a beast yet, but I don't see why it
wouldn't work? This series uses it for cases where annotations are pulled
in via #includes, so a file #include'ing itself should be any different,
as far as I can imagine.

  + */
  +#define QIDL(...) QIDL(__VA_ARGS__)
  +#define QIDL_START(...) QIDL_START(__VA_ARGS__)
  +#define QIDL_END(...) QIDL_END(__VA_ARGS__)
  +
  +#define QIDL_VISIT_TYPE(...)
  +#define QIDL_SCHEMA_ADD_LINK(...)
  +#define QIDL_PROPERTIES(...)
 
 Maybe for this pass, the macros which do nothing like above could
 still do more syntax checking by specifying the macro argument list
 instead of ellipsis or even by introducing a dummy inline function.
 
  +
  +#else /* !QIDL_GEN */
  +
  +#define QIDL(...)
  +#define QIDL_START(name, ...)
 
 Declare 'struct type of name' here (see below)?
 

I'd like to keep it more general so we can do things like annotate
unions/enums/etc if need be, and also to be able to easily define
away all the QIDL annotations via configure to identity build
issues potentially caused by QIDL.

Not sure, but I think it may also cause some annoyances for cscope/ctags
users, or even just grepping for a type definition.

  +#define QIDL_END(name) \
  +static struct { \
 
 'const', how about a name for the struct type too?
 
  +void (*visitor)(Visitor *, struct name **, const char *, Error 
  **); \
 
 Here 'struct name **' could be const if the struct defined here is
 const. Probably 'struct name' should be declared earlier.
 

Taking a 'const struct name **' and passing it in as a 'struct name**'?

If so, I think this comes down to enforcing non-const structs by having QIDL
generate the declaration, or just letting the build generate a warning. The
former is safer, but for the reasons above I'd prefer the latter since it
allows us to use plain C for type declarations.

  +const char *schema_json_text; \
  +Object *schema_obj; \
  +Property *properties; \
  +} qidl_data_##name;
  +
  +#define QIDL_VISIT_TYPE(name, v, s, f, e) qidl_data_##name.visitor(v, s, 
  f, e)
  +#define QIDL_SCHEMA_ADD_LINK(name, obj, path, errp) \
  +object_property_add_link(obj, path, container, \
  + qidl_data_##name.schema_obj, errp);
 
 The semicolons here and below seem useless.
 
  +#define QIDL_PROPERTIES(name) qidl_data_##name.properties;
  +
  +#endif /* QIDL_GEN */
  +
  +#endif
  --
  1.7.9.5
 
 
 



Re: [Qemu-devel] [PATCH v2 00/16] net: Move legacy QEMU VLAN code into net/hub.c

2012-07-24 Thread Laszlo Ersek
I'd like to review v2 tomorrow (ahem, today), ie. not right now, but
this catches my eye:

On 07/24/12 17:35, Stefan Hajnoczi wrote:

  * Drop spurious closesocket(fd), probably merge conflict [Stefan]

I saw it last time and I thought you had fixed a leak with it on the
side. The function looks as follows (right after applying [01 .. 02]
from v1):

[net/socket.c]

  376  static void net_socket_accept(void *opaque)
  377  {
  378  NetSocketListenState *s = opaque;
  379  NetSocketState *s1;
  380  struct sockaddr_in saddr;
  381  socklen_t len;
  382  int fd;
  383
  384  for(;;) {
  385  len = sizeof(saddr);
  386  fd = qemu_accept(s-fd, (struct sockaddr *)saddr, len);
  387  if (fd  0  errno != EINTR) {
  388  return;
  389  } else if (fd = 0) {
  390  break;
  391  }
  392  }
  393  s1 = net_socket_fd_init(s-peer, s-model, s-name, fd, 1);
  394  if (!s1) {
  395  closesocket(fd);
  396  } else {
  397  snprintf(s1-nc.info_str, sizeof(s1-nc.info_str),
  398   socket: connection from %s:%d,
  399   inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
  400  }
  401  }

If net_socket_fd_init() fails, then the file descriptor extracted by
qemu_accept() should be closed. The fix is not strongly related to the
series but I figured I'd let it slide :)

... Oh. net_socket_fd_init() takes ownership even if it fails, in which
case it calls closesocket() itself.

Such functions need a banner :)

Laszlo



Re: [Qemu-devel] [PULL] pci,msi,virtio

2012-07-24 Thread Alexey Kardashevskiy

On 24/07/12 21:32, Andreas Färber wrote:

Am 23.07.2012 20:29, schrieb Alex Williamson:

On Mon, 2012-07-23 at 13:16 -0500, Anthony Liguori wrote:

On 07/23/2012 12:05 PM, Alex Williamson wrote:

Looks like it merged ok for me, but you'll need this to complete the
PCIUnregisterFunc conversion.  Not sure how this built in MST's tree.
Anthony, it'd be great if we could merge and fix this in your tree since
MST is out of the office.


I can't fix it without rewriting git history or breaking bisection which isn't
something I'm really willing to do.

When does MST get back?  If it's not for a while, I can merge it all manually
with a fixup.


Next week, so (unfortunately for me) probably not worth you messing with
it.


So Anthony, how urgent is your/Wanpeng's i440fx rework and through whose
queue is that supposed to go? Can you wait for mst's return? Or do you
want to handle it yourself and have mst rebase on it while at it?

My pci-host branch [1] is updated with mst's requested spapr_pci.c code
movement, so I just need to know whether to rebase on some other branch
and when to re-post. Soft Freeze is in three weeks iirc.



A bit curious - where is spapr_pci.c going to be moved to?




Regards,
Andreas

[1] http://repo.or.cz/w/qemu/afaerber.git/shortlog/refs/heads/pci-host




--
Alexey



[Qemu-devel] Possible bug in cirrus_vga.c vs. HDR handling

2012-07-24 Thread Benjamin Herrenschmidt
Hi folks !

I was debugging a problem with 16bpp support, when I found out that
my attempts at writing to the Hidden DAC Register were not working.

The reason was that I (well, cirrusdrmfb really) was doing the sequence
READ, READ, READ, READ, WRITE (to the DAC mask register), which should
have worked, except that the code in qemu for reads does:

static int cirrus_read_hidden_dac(CirrusVGAState * s)
{
if (++s-cirrus_hidden_dac_lockindex == 5) {
s-cirrus_hidden_dac_lockindex = 0;
return s-cirrus_hidden_dac_data;
}
return 0xff;
}

(Note the *pre*increment)

And s-cirrus_hidden_dac_lockindex is initialized in  cirrus_reset() to:

 s-cirrus_hidden_dac_lockindex = 5;

So the first 4 reads cause it to go to 6,7,8,9... and never
actually wrap back, so the write doesn't work as it checks for
the value being exactly 4.

Now, that -might- mimmic the real HW (I've added a workaround to drmfb
that does a dummy write first), but it looks dubious to me.

Shouldn't we initialize the lockindex to 0 in reset ? or to 4 ?

Cheers,
Ben.





Re: [Qemu-devel] [RFC 0/9] vhost-scsi: Add support for host virtualized target

2012-07-24 Thread Zhi Yong Wu
On Wed, Jul 25, 2012 at 6:33 AM, Nicholas A. Bellinger
n...@linux-iscsi.org wrote:
 From: Nicholas Bellinger n...@linux-iscsi.org

 Hi Anthony + QEMU storage folks,

 The following is a reviewable RFC series of vhost-scsi against yesterday's
 QEMU.git/master @ commit 401a66357d.

 The series is available directly from:

   git://git.kernel.org/pub/scm/virt/kvm/nab/qemu-kvm.git vhost-scsi-merge
Is this git tree cloned from qemu-kvm.git/master or qemu.git/master?
But from above info, it seems to be from latter. I got confused.


 It contains the squashed + re-ordered patches from Stefan - Zhi's QEMU
 original work into a updated series against recent QEMU code.

 As mentioned recently on qemu-devel here:

   http://lists.gnu.org/archive/html/qemu-devel/2012-07/msg03280.html

 the 'vhost-scsi-merge' branch is currently failing with vhost/virtio
 errors using the latest HEAD.  Stefan + myself are currently working through
 the 1.1.0 regressions, and will be posting incremental patches against this
 working tree as individual progress is made..

 Please have a look.

 --nab

 P.S:

 Also, for folks who are interested in trying out a working virtio-scsi - 
 tcm_vhost
 setup, check out using branch 'vhost-scsi' with the last pre-regression
 commit from upstream QEMU that appears to be performing very well.

 This along with target-pending.git/for-next-merge for KVM host + a virtio-scsi
 SCSI LLD bugfix for KVM guest that's headed into 3.6-rc1 here should be enough
 to get up and running:

 virtio-scsi: Add vdrv-scan for post VIRTIO_CONFIG_S_DRIVER_OK LUN scanning
 http://git.kernel.org/?p=linux/kernel/git/jejb/scsi.git;a=commitdiff;h=59057fbc37178f10a196ab7ec170b80273f75a47;hp=0b1017aab197271a78169fde3d7e487bb721997c

 Thanks!

 Nicholas Bellinger (1):
   virtio-scsi: Set max_target=0 during vhost-scsi operation

 Stefan Hajnoczi (8):
   notifier: add validity check and notify function
   virtio-pci: support host notifiers in TCG mode
   virtio-pci: check that event notification worked
   vhost: Pass device path to vhost_dev_init()
   virtio-scsi: Add wwpn and tgpt properties
   virtio-scsi: Open and initialize /dev/vhost-scsi
   virtio-scsi: Start/stop vhost
   vhost-scsi: add -vhost-scsi host device

  configure|   10 +++
  event_notifier.c |   21 ++
  event_notifier.h |4 +
  hw/Makefile.objs |1 +
  hw/qdev-properties.c |   32 +
  hw/qdev.h|3 +
  hw/vhost-scsi.c  |  173 
 ++
  hw/vhost-scsi.h  |   50 ++
  hw/vhost.c   |5 +-
  hw/vhost.h   |3 +-
  hw/vhost_net.c   |2 +-
  hw/virtio-pci.c  |   28 +++-
  hw/virtio-scsi.c |   59 +-
  hw/virtio-scsi.h |1 +
  hw/virtio.c  |7 ++
  qemu-common.h|1 +
  qemu-config.c|   16 +
  qemu-options.hx  |4 +
  vl.c |   18 +
  19 files changed, 430 insertions(+), 8 deletions(-)
  create mode 100644 hw/vhost-scsi.c
  create mode 100644 hw/vhost-scsi.h

 --
 1.7.2.5

 --
 You received this message because you are subscribed to the Google Groups 
 Linux-iSCSI.org Target Development group.
 To post to this group, send email to linux-iscsi-target-...@googlegroups.com.
 To unsubscribe from this group, send email to 
 linux-iscsi-target-dev+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/linux-iscsi-target-dev?hl=en.




-- 
Regards,

Zhi Yong Wu



Re: [Qemu-devel] [PATCH v10 00/15] QEMU OpenRISC support

2012-07-24 Thread Jia Liu
ping

On Fri, Jul 20, 2012 at 3:50 PM, Jia Liu pro...@gmail.com wrote:
 This is the OpenCores OpenRISC 1200 support for QEMU.
 Full implementation of the system-model and linux-user-model support.

 OpenRISC 1200 is a OpenCores open source CPU,
 its architecture manual can be found at
 http://opencores.org/svnget,or1k?file=/trunk/docs/openrisc_arch.pdf

 A OpenRISC Linux kernel contain initramfs for qemu-system-or32 testing
 can be found at
 https://docs.google.com/file/d/0BxeTrz3x0CBLSjR3Sk5Vd3h1eDA/edit?pli=1

 A OpenRISC hello-world program for qemu-or32 testing can be found at
 https://docs.google.com/file/d/0BxeTrz3x0CBLN3RSWUFNYktrU2M/edit?pli=1

 Signed-off-by: Jia Liu pro...@gmail.com
 ---

 Version History:

 v10:
 Addressed Peter's review comments:
 - replace field() with extract32() using for decode

 Addressed Max's review comments:
 - reimplement l.ff1 and l.fl1 by using ctz32() and clz32()
 - make helper func mul32 a pure 32bits mul implementation
 - add a testcase for l.mul* overflow check

 Addressed MaxBlue's review comments:
 - enforced instructions can be only accessible in supervisor mode
 - add exception check in softmmu mode if the CPU is not in supervisor mode

 v9:
 Addressed Blue's review comments:
 - fix jump instructions
 - fix some instruction decoding

 Addressed AndreasPaolo's review comments:
 - rename intrpt*.c to interrupt*.c
 - use one-space indentation in Copyright Notice
 - remove unused header in cpu.c
 - remove/comment unimplement or64 code
 - remove unused macro
 - move feature into OpenRISCCPU from CPUOpenRISCState
 - move tcg_inited into initfn
 - remove reset in openrisc_*_initfn

 -combine target-machine into target-stubs

 v8:
 Addressed Max's review comments:
 - fix l.div*.

 Addressed Blue's review comments:
 - using qemu_log instead of printf.

 Addressed Peter's review comments:
 - fix load_kernel.

 Addressed PeterAndreas's review comments:
 - thanks Andreas's r178 example, switch to QOM from CPUArchState.

 v7:
 Addressed Max's review comments:
 - fix l.div*.
 - add a div testcase.
 - add return -1 to every failed test.

 Addressed Peter's review comments:
 - fix load_kernel().

 Addressed WeiRen's review comments:
 - fix typo, l.div and load_kernel().

 v6:
 Addressed Blue's review comments:
 - reimplement l.mul* l.mfspr.
 - fix l.mtspr l.sub.
 - some English typo fix.
 - some coding style fix.

 Addressed Max's review comments:
 - replace NE2000 with OpenCores 10/100 ethernet adapter, thanks for his patch.

 v5:
 Addressed Blue's review comments:
 - reimplement l.mul* l.mtspr l.add* l.sub* and more.
 - shoot bugs with --enable-debug-tcg.

 v4:
 Addressed Max's review comments:
 - fix l.div l.mac* l.mul*, and more.

 Addressed Richard, Wei-Ren and Andreas's review comments:
 - replace tcg_temp_new_i32 with tcg_temp_local_new_i32 in l.div translation.

 Addressed Andreas's review comments:
 - update to suit Makefile system.

 - add UPR CPUCFGR and MMUCFGR impelement.
 - add instruction check functions.

 v3:
 Addressed Stefan and Andreas's review comments:
 - use QEMU and OpenRISC's official name.

 Addressed Andreas's review comments:
 - reimplement cpu QOM.
 - combine target stubs and QOM implement.
 - use new commit message and subject.

 Addressed Max's review comments:
 - handle div zero exception.
 - reimplement float point instructions.
 - fix l.mac*, l.mul*, and more.

 v2:
 Addressed Malc, Weiren, Andreas and Blue's review comments:
 - reimplement cpu QOM.

 Addressed Andreas's review comments:
 - reimplement machine.
 - rewrite the Copyright Notice using better format.

 Addressed Blue and Weiren's review comments:
 - compiling with AREG0 and remove global env, no dyngen-exe longer.

 Addressed Max, Blue and Weiren's review comments:
 - handle div zero exception.
 - handle illegal instruction.

 Addressed Blue's review comments:
 - separate do_interrupt into intrpt.c form intrpt_helper.c.
 - add QEMU_NORETURN to raise_exception.
 - reimplement float instrutions.
 - fix type of linux syscall and termbits.
 - reimplement sim board.
 - use the LGPL web URL in Copyright Notice.
 - reimplemt branch instructions.

 - split taregt stubs, QOM and machine.

 v1:
 - add QEMU OpenRISC support.
 - well tested on x64 machine, and final tested x86 machine.

 Jia Liu (15):
   target-or32: Add target stubs and QOM cpu
   target-or32: Add MMU support
   target-or32: Add interrupt support
   target-or32: Add exception support
   target-or32: Add int instruction helpers
   target-or32: Add float instruction helpers
   target-or32: Add instruction translation
   target-or32: Add PIC support
   target-or32: Add timer support
   target-or32: Add a IIS dummy board
   target-or32: Add system instructions
   target-or32: Add gdb stub support
   target-or32: Add linux syscall, signal and termbits
   target-or32: Add linux user support
   target-or32: Add testcses

  arch_init.c |2 +
  arch_init.h |1 +
  configure 

Re: [Qemu-devel] Synchronize issue and lost character when using serial as pipe type

2012-07-24 Thread Wei Xu
Thanks, I'll try it and update later.

On Tue, Jul 24, 2012 at 7:36 PM, 陳韋任 (Wei-Ren Chen) 
che...@iis.sinica.edu.tw wrote:

 On Tue, Jul 24, 2012 at 07:32:44PM +0800, Wei Xu wrote:
  Hi Folks,
  I am trying to install FreeBSD9.0 with xen4.0.2 and qemu 0.10.2, and try
 to set
  up a kernel debug host pair using the serial with pipe type,
  after tried and failed for a lot of times and then I come here for some
 help,
  here is my info.

   QEMU 0.10 is really old. Have you ever considered using current
 release?

 Regards,
 chenwj

 --
 Wei-Ren Chen (陳韋任)
 Computer Systems Lab, Institute of Information Science,
 Academia Sinica, Taiwan (R.O.C.)
 Tel:886-2-2788-3799 #1667
 Homepage: http://people.cs.nctu.edu.tw/~chenwj



[Qemu-devel] [PATCH 0/5] prepare unplug out of protection of global lock

2012-07-24 Thread Liu Ping Fan
refer to orignal plan posted by Marcelo Tosatti,
http://lists.gnu.org/archive/html/qemu-devel/2012-06/msg04315.html

These patches protect DeviceState's rd from reclaimer. It is neccessary
when no qemu_global_lock protects between them.



[Qemu-devel] [PATCH 1/5] qom: adopt rwlock to protect accessing dev from removing it

2012-07-24 Thread Liu Ping Fan
From: Liu Ping Fan pingf...@linux.vnet.ibm.com

rwlock:
  qemu_device_tree_mutex

rd side:
  --device_del(destruction of device will be postphoned until unplug
ack from guest),
  --pci hot-unplug
  --iteration (qdev_reset_all)

wr side:
  --device_add

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 hw/pci-hotplug.c  |4 
 hw/qdev-monitor.c |   17 -
 hw/qdev.c |2 ++
 3 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index e7fb780..b3b88c1 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -265,9 +265,11 @@ static int pci_device_hot_remove(Monitor *mon, const char 
*pci_addr)
 return -1;
 }
 
+qemu_rwlock_rdlock_devtree();
 d = pci_find_device(pci_find_root_bus(dom), bus, PCI_DEVFN(slot, 0));
 if (!d) {
 monitor_printf(mon, slot %d empty\n, slot);
+qemu_rwlock_unlock_devtree();
 return -1;
 }
 
@@ -275,9 +277,11 @@ static int pci_device_hot_remove(Monitor *mon, const char 
*pci_addr)
 if (error_is_set(local_err)) {
 monitor_printf(mon, %s\n, error_get_pretty(local_err));
 error_free(local_err);
+qemu_rwlock_unlock_devtree();
 return -1;
 }
 
+qemu_rwlock_unlock_devtree();
 return 0;
 }
 
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 7915b45..8aec067 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -429,14 +429,18 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 
 /* find bus */
 path = qemu_opt_get(opts, bus);
+
+qemu_rwlock_wrlock_devtree();
 if (path != NULL) {
 bus = qbus_find(path);
 if (!bus) {
+qemu_rwlock_unlock_devtree();
 return NULL;
 }
 if (strcmp(object_get_typename(OBJECT(bus)), k-bus_type) != 0) {
 qerror_report(QERR_BAD_BUS_FOR_DEVICE,
   driver, object_get_typename(OBJECT(bus)));
+qemu_rwlock_unlock_devtree();
 return NULL;
 }
 } else {
@@ -444,11 +448,13 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 if (!bus) {
 qerror_report(QERR_NO_BUS_FOR_DEVICE,
   driver, k-bus_type);
+qemu_rwlock_unlock_devtree();
 return NULL;
 }
 }
 if (qdev_hotplug  !bus-allow_hotplug) {
 qerror_report(QERR_BUS_NO_HOTPLUG, bus-name);
+qemu_rwlock_unlock_devtree();
 return NULL;
 }
 
@@ -466,6 +472,7 @@ DeviceState *qdev_device_add(QemuOpts *opts)
 }
 if (qemu_opt_foreach(opts, set_property, qdev, 1) != 0) {
 qdev_free(qdev);
+qemu_rwlock_unlock_devtree();
 return NULL;
 }
 if (qdev-id) {
@@ -478,6 +485,8 @@ DeviceState *qdev_device_add(QemuOpts *opts)
   OBJECT(qdev), NULL);
 g_free(name);
 }
+qemu_rwlock_unlock_devtree();
+
 if (qdev_init(qdev)  0) {
 qerror_report(QERR_DEVICE_INIT_FAILED, driver);
 return NULL;
@@ -600,13 +609,19 @@ void qmp_device_del(const char *id, Error **errp)
 {
 DeviceState *dev;
 
+/* protect against unplug ack from guest, where we really remove device
+ * from system
+ */
+qemu_rwlock_rdlock_devtree();
 dev = qdev_find_recursive(sysbus_get_default(), id);
 if (NULL == dev) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, id);
+qemu_rwlock_unlock_devtree();
 return;
 }
-
+/* Just remove from system, and drop refcnt there*/
 qdev_unplug(dev, errp);
+qemu_rwlock_unlock_devtree();
 }
 
 void qdev_machine_init(void)
diff --git a/hw/qdev.c b/hw/qdev.c
index af54467..ac55e45 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -230,7 +230,9 @@ static int qbus_reset_one(BusState *bus, void *opaque)
 
 void qdev_reset_all(DeviceState *dev)
 {
+qemu_rwlock_rdlock_devtree();
 qdev_walk_children(dev, qdev_reset_one, qbus_reset_one, NULL);
+qemu_rwlock_unlock_devtree();
 }
 
 void qbus_reset_all_fn(void *opaque)
-- 
1.7.4.4




[Qemu-devel] [PATCH 2/5] exec.c: use refcnt to protect device during dispatching

2012-07-24 Thread Liu Ping Fan
From: Liu Ping Fan pingf...@linux.vnet.ibm.com

acquire device's refcnt with qemu_device_tree_mutex rwlock, so we
can safely handle it when mmio dispatch.

If in radix-tree, leaf is subpage, then move further step to acquire
opaque which is the type --DeiveState.

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 exec.c   |   38 ++
 memory.h |2 ++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/exec.c b/exec.c
index 8244d54..d2a6d08 100644
--- a/exec.c
+++ b/exec.c
@@ -3032,6 +3032,30 @@ static void subpage_write(void *opaque, 
target_phys_addr_t addr,
 io_mem_write(section-mr, addr, value, len);
 }
 
+static MemoryRegionSection *subpage_get_backend(subpage_t *mmio,
+target_phys_addr_t addr)
+{
+MemoryRegionSection *section;
+unsigned int idx = SUBPAGE_IDX(addr);
+
+section = phys_sections[mmio-sub_section[idx]];
+return section;
+}
+
+void *get_backend(MemoryRegion* mr,  target_phys_addr_t addr)
+{
+MemoryRegionSection *p;
+Object *ret;
+
+if (mr-subpage) {
+p = subpage_get_backend(mr-opaque, addr);
+ret = OBJECT(p-mr-opaque);
+} else {
+ret = OBJECT(mr-opaque);
+}
+return ret;
+}
+
 static const MemoryRegionOps subpage_ops = {
 .read = subpage_read,
 .write = subpage_write,
@@ -3396,13 +3420,25 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
 uint32_t val;
 target_phys_addr_t page;
 MemoryRegionSection *section;
+Object *bk;
 
 while (len  0) {
 page = addr  TARGET_PAGE_MASK;
 l = (page + TARGET_PAGE_SIZE) - addr;
 if (l  len)
 l = len;
+
+qemu_rwlock_rdlock_devtree();
 section = phys_page_find(page  TARGET_PAGE_BITS);
+if (!(memory_region_is_ram(section-mr) ||
+memory_region_is_romd(section-mr))  !is_write) {
+bk = get_backend(section-mr, addr);
+object_ref(bk);
+} else if (!memory_region_is_ram(section-mr)  is_write) {
+bk = get_backend(section-mr, addr);
+object_ref(bk);
+}
+qemu_rwlock_unlock_devtree();
 
 if (is_write) {
 if (!memory_region_is_ram(section-mr)) {
@@ -3426,6 +3462,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
 io_mem_write(section-mr, addr1, val, 1);
 l = 1;
 }
+object_unref(bk);
 } else if (!section-readonly) {
 ram_addr_t addr1;
 addr1 = memory_region_get_ram_addr(section-mr)
@@ -3464,6 +3501,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
 stb_p(buf, val);
 l = 1;
 }
+object_unref(bk);
 } else {
 /* RAM case */
 ptr = qemu_get_ram_ptr(section-mr-ram_addr
diff --git a/memory.h b/memory.h
index 740c48e..e5a86dc 100644
--- a/memory.h
+++ b/memory.h
@@ -748,6 +748,8 @@ void memory_global_dirty_log_stop(void);
 
 void mtree_info(fprintf_function mon_printf, void *f);
 
+void *get_backend(MemoryRegion* mr,  target_phys_addr_t addr);
+
 #endif
 
 #endif
-- 
1.7.4.4




[Qemu-devel] [PATCH 3/5] hotplug: introduce qdev_unplug_ack() to remove device from views

2012-07-24 Thread Liu Ping Fan
From: Liu Ping Fan pingf...@linux.vnet.ibm.com

When guest confirm the removal of device, we should
--unmap from MemoryRegion view
--isolated from device tree view

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 hw/acpi_piix4.c |4 ++--
 hw/qdev.c   |   28 
 hw/qdev.h   |3 ++-
 3 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 0aace60..c174247 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -305,8 +305,8 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned 
slots)
 if (pc-no_hotplug) {
 slot_free = false;
 } else {
-object_unparent(OBJECT(dev));
-qdev_free(qdev);
+/* refcnt will be decreased */
+qdev_unplug_ack(qdev, NULL);
 }
 }
 }
diff --git a/hw/qdev.c b/hw/qdev.c
index ac55e45..3f7dfa5 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -104,6 +104,14 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
 bus_add_child(bus, dev);
 }
 
+static void qdev_unset_parent(DeviceState *dev)
+{
+BusState *b = dev-parent_bus;
+
+object_unparent(OBJECT(dev));
+bus_remove_child(b, dev);
+}
+
 /* Create a new device.  This only initializes the device state structure
and allows properties to be set.  qdev_init should be called to
initialize the actual device emulation.  */
@@ -194,6 +202,26 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int 
alias_id,
 dev-alias_required_for_version = required_for_version;
 }
 
+static int qdev_unmap(DeviceState *dev)
+{
+DeviceClass *dc =  DEVICE_GET_CLASS(dev);
+if (dc-unmap) {
+dc-unmap(dev);
+}
+return 0;
+}
+
+void qdev_unplug_ack(DeviceState *dev, Error **errp)
+{
+qemu_rwlock_wrlock_devtree();
+/* isolate from device tree */
+qdev_unset_parent(dev);
+/* isolate from mem view */
+qdev_unmap(dev);
+qemu_rwlock_unlock_devtree();
+object_unref(OBJECT(dev));
+}
+
 void qdev_unplug(DeviceState *dev, Error **errp)
 {
 DeviceClass *dc = DEVICE_GET_CLASS(dev);
diff --git a/hw/qdev.h b/hw/qdev.h
index f4683dc..fc5ff02 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -47,7 +47,7 @@ typedef struct DeviceClass {
 
 /* callbacks */
 void (*reset)(DeviceState *dev);
-
+void (*unmap)(DeviceState *dev);
 /* device state */
 const VMStateDescription *vmsd;
 
@@ -162,6 +162,7 @@ void qdev_init_nofail(DeviceState *dev);
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
  int required_for_version);
 void qdev_unplug(DeviceState *dev, Error **errp);
+void qdev_unplug_ack(DeviceState *dev, Error **errp);
 void qdev_free(DeviceState *dev);
 int qdev_simple_unplug_cb(DeviceState *dev);
 void qdev_machine_creation_done(void);
-- 
1.7.4.4




[Qemu-devel] [PATCH 5/5] e1000: using new interface--unmap to unplug

2012-07-24 Thread Liu Ping Fan
From: Liu Ping Fan pingf...@linux.vnet.ibm.com

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 hw/e1000.c |   15 +--
 1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index 4573f13..4c1e141 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1192,6 +1192,18 @@ e1000_cleanup(VLANClientState *nc)
 s-nic = NULL;
 }
 
+static void
+pci_e1000_unmap(DeviceState *dev)
+{
+PCIDevice *p = PCI_DEVICE(dev);
+E1000State *d = DO_UPCAST(E1000State, dev, p);
+
+/* DO NOT FREE anything!until refcnt=0 */
+/* isolate from memory view */
+memory_region_destroy(d-mmio);
+memory_region_destroy(d-io);
+}
+
 static int
 pci_e1000_uninit(PCIDevice *dev)
 {
@@ -1199,8 +1211,6 @@ pci_e1000_uninit(PCIDevice *dev)
 
 qemu_del_timer(d-autoneg_timer);
 qemu_free_timer(d-autoneg_timer);
-memory_region_destroy(d-mmio);
-memory_region_destroy(d-io);
 qemu_del_vlan_client(d-nic-nc);
 return 0;
 }
@@ -1283,6 +1293,7 @@ static void e1000_class_init(ObjectClass *klass, void 
*data)
 k-class_id = PCI_CLASS_NETWORK_ETHERNET;
 dc-desc = Intel Gigabit Ethernet;
 dc-reset = qdev_e1000_reset;
+dc-unmap = pci_e1000_unmap;
 dc-vmsd = vmstate_e1000;
 dc-props = e1000_properties;
 }
-- 
1.7.4.4




Re: [Qemu-devel] [PATCH v5 6/6] block: Enable qemu_open/close to work with fd sets

2012-07-24 Thread Corey Bryant



On 07/24/2012 08:07 AM, Kevin Wolf wrote:

Am 23.07.2012 15:08, schrieb Corey Bryant:

When qemu_open is passed a filename of the /dev/fdset/nnn
format (where nnn is the fdset ID), an fd with matching access
mode flags will be searched for within the specified monitor
fd set.  If the fd is found, a dup of the fd will be returned
from qemu_open.

Each fd set has a reference count.  The purpose of the reference
count is to determine if an fd set contains file descriptors that
have open dup() references that have not yet been closed.  It is
incremented on qemu_open and decremented on qemu_close.  It is
not until the refcount is zero that file desriptors in an fd set
can be closed.  If an fd set has dup() references open, then we
must keep the other fds in the fd set open in case a reopen
of the file occurs that requires an fd with a different access
mode.

Signed-off-by: Corey Bryant cor...@linux.vnet.ibm.com

v2:
  -Get rid of file_open and move dup code to qemu_open
   (kw...@redhat.com)
  -Use strtol wrapper instead of atoi (kw...@redhat.com)

v3:
  -Add note about fd leakage (ebl...@redhat.com)

v4
  -Moved patch to be later in series (lcapitul...@redhat.com)
  -Update qemu_open to check access mode flags and set flags that
   can be set (ebl...@redhat.com, kw...@redhat.com)

v5:
  -This patch was overhauled quite a bit in this version, with
   the addition of fd set and refcount support.
  -Use qemu_set_cloexec() on dup'd fd (ebl...@redhat.com)
  -Modify flags set by fcntl on dup'd fd (ebl...@redhat.com)
  -Reduce syscalls when setting flags for dup'd fd (ebl...@redhat.com)
  -Fix O_RDWR, O_RDONLY, O_WRONLY checks (ebl...@redhat.com)
---
  block/raw-posix.c |   24 +-
  block/raw-win32.c |2 +-
  block/vmdk.c  |4 +-
  block/vpc.c   |2 +-
  block/vvfat.c |   12 ++---
  cutils.c  |5 ++
  monitor.c |   85 +
  monitor.h |4 ++
  osdep.c   |  138 -
  qemu-common.h |3 +-
  qemu-tool.c   |   12 +
  11 files changed, 267 insertions(+), 24 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index a172de3..5d0a801 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -271,7 +271,7 @@ static int raw_open_common(BlockDriverState *bs, const char 
*filename,
  out_free_buf:
  qemu_vfree(s-aligned_buf);
  out_close:
-qemu_close(fd);
+qemu_close(fd, filename);
  return -errno;
  }


Hm, not a nice interface where qemu_close() needs the filename and
(worse) could be given a wrong filename. Maybe it would be better to
maintain a list of fd - fdset mappings in qemu_open/close?



I agree, I don't really like it either.

We already have a list of fd - fdset mappings (mon_fdset_fd_t - 
mon_fdset_t).  Would it be too costly to loop through all the fdsets/fds 
at the beginning of every qemu_close()?



But if we decided to keep it like this, please use the right interface
from the beginning in patch 5 instead of updating it here.



Ok


@@ -2551,6 +2551,91 @@ static void monitor_fdsets_set_in_use(Monitor *mon, bool 
in_use)
  }
  }

+void monitor_fdset_increment_refcount(Monitor *mon, int64_t fdset_id)
+{
+mon_fdset_t *mon_fdset;
+
+if (!mon) {
+return;
+}
+
+QLIST_FOREACH(mon_fdset, mon-fdsets, next) {
+if (mon_fdset-id == fdset_id) {
+mon_fdset-refcount++;
+break;
+}
+}
+}
+
+void monitor_fdset_decrement_refcount(Monitor *mon, int64_t fdset_id)
+{
+mon_fdset_t *mon_fdset;
+
+if (!mon) {
+return;
+}
+
+QLIST_FOREACH(mon_fdset, mon-fdsets, next) {
+if (mon_fdset-id == fdset_id) {
+mon_fdset-refcount--;
+if (mon_fdset-refcount == 0) {
+monitor_fdset_cleanup(mon_fdset);
+}
+break;
+}
+}
+}


These two functions are almost the same. Would a
monitor_fdset_update_refcount(mon, fdset_id, value) make sense? These
functions could then be kept as thin wrappers around it, or they could
even be dropped completely.



This makes sense and I'll try one of these approaches.  I actually 
started to do something along these lines in v5 but reverted back to the 
two independent functions because it was easier to read the code.



+
+int monitor_fdset_get_fd(Monitor *mon, int64_t fdset_id, int flags)
+{
+mon_fdset_t *mon_fdset;
+mon_fdset_fd_t *mon_fdset_fd;
+int mon_fd_flags;
+
+if (!mon) {
+errno = ENOENT;
+return -1;
+}
+
+QLIST_FOREACH(mon_fdset, mon-fdsets, next) {
+if (mon_fdset-id != fdset_id) {
+continue;
+}
+QLIST_FOREACH(mon_fdset_fd, mon_fdset-fds, next) {
+if (mon_fdset_fd-removed) {
+continue;
+}
+
+mon_fd_flags = fcntl(mon_fdset_fd-fd, F_GETFL);
+if (mon_fd_flags == -1) {
+return -1;
+}

Re: [Qemu-devel] [PATCH v5 0/6] file descriptor passing using fd sets

2012-07-24 Thread Corey Bryant



On 07/24/2012 08:09 AM, Kevin Wolf wrote:

Am 23.07.2012 15:07, schrieb Corey Bryant:

Corey Bryant (6):
   qemu-char: Add MSG_CMSG_CLOEXEC flag to recvmsg
   qapi: Introduce add-fd, remove-fd, query-fdsets
   monitor: Clean up fd sets on monitor disconnect
   block: Convert open calls to qemu_open
   block: Convert close calls to qemu_close
   block: Enable qemu_open/close to work with fd sets

  block/raw-posix.c |   42 -
  block/raw-win32.c |6 +-
  block/vdi.c   |5 +-
  block/vmdk.c  |   25 +++---
  block/vpc.c   |4 +-
  block/vvfat.c |   16 ++--
  cutils.c  |5 ++
  monitor.c |  244 -
  monitor.h |4 +
  osdep.c   |  141 +++
  qapi-schema.json  |   97 +
  qemu-char.c   |   10 ++-
  qemu-common.h |2 +
  qemu-tool.c   |   12 +++
  qmp-commands.hx   |  121 ++
  savevm.c  |4 +-
  16 files changed, 684 insertions(+), 54 deletions(-)


Apart from the points I commented on in patch 6, and what Eric and you
found, this looks good to me.

Kevin



Great, thanks for the review!

--
Regards,
Corey





[Qemu-devel] [PATCH 4/5] qom: delay DeviceState's reclaim to main-loop

2012-07-24 Thread Liu Ping Fan
From: Liu Ping Fan pingf...@linux.vnet.ibm.com

iohandler/bh/timer may use DeviceState when its refcnt=0,
postpone the reclaimer till they have done with it.

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 include/qemu/object.h |2 +-
 main-loop.c   |4 
 main-loop.h   |2 ++
 qemu-tool.c   |4 
 qom/Makefile.objs |2 +-
 qom/object.c  |7 ++-
 qom/reclaimer.c   |   41 +
 7 files changed, 59 insertions(+), 3 deletions(-)
 create mode 100644 qom/reclaimer.c

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 8b17776..b233ee4 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -958,5 +958,5 @@ int object_child_foreach(Object *obj, int (*fn)(Object 
*child, void *opaque),
  */
 Object *container_get(Object *root, const char *path);
 
-
+void qemu_reclaimer_enqueue(Object *obj);
 #endif
diff --git a/main-loop.c b/main-loop.c
index eb3b6e6..f9cecc5 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -505,5 +505,9 @@ int main_loop_wait(int nonblocking)
them.  */
 qemu_bh_poll();
 
+/* ref to device from iohandler/bh/timer do not obey the rules, so delay
+ * reclaiming until now.
+ */
+qemu_device_reclaimer();
 return ret;
 }
diff --git a/main-loop.h b/main-loop.h
index cedddf5..1a59a6d 100644
--- a/main-loop.h
+++ b/main-loop.h
@@ -367,4 +367,6 @@ void qemu_bh_schedule_idle(QEMUBH *bh);
 int qemu_bh_poll(void);
 void qemu_bh_update_timeout(uint32_t *timeout);
 
+void qemu_device_reclaimer(void);
+
 #endif
diff --git a/qemu-tool.c b/qemu-tool.c
index 318c5fc..34d959b 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -75,6 +75,10 @@ void qemu_mutex_unlock_iothread(void)
 {
 }
 
+void qemu_device_reclaimer(void)
+{
+}
+
 int use_icount;
 
 void qemu_clock_warp(QEMUClock *clock)
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 5ef060a..a579261 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,4 +1,4 @@
-qom-obj-y = object.o container.o qom-qobject.o
+qom-obj-y = object.o container.o qom-qobject.o reclaimer.o
 qom-obj-twice-y = cpu.o
 common-obj-y = $(qom-obj-twice-y)
 user-obj-y = $(qom-obj-twice-y)
diff --git a/qom/object.c b/qom/object.c
index 00bb3b0..227d966 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -649,7 +649,12 @@ void object_unref(Object *obj)
 
 /* parent always holds a reference to its children */
 if (obj-ref == 0) {
-object_finalize(obj);
+/* fixme, maybe introduce obj-finalze to make this more elegant */
+if (object_dynamic_cast(obj, TYPE_DEVICE) != NULL) {
+qemu_reclaimer_enqueue(obj);
+} else {
+object_finalize(obj);
+}
 }
 }
 
diff --git a/qom/reclaimer.c b/qom/reclaimer.c
new file mode 100644
index 000..2fb3410
--- /dev/null
+++ b/qom/reclaimer.c
@@ -0,0 +1,41 @@
+/*
+ * QEMU DeviceState reclaimer
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include qemu-common.h
+#include qemu-thread.h
+#include main-loop.h
+#include qemu/object.h
+
+typedef struct Chunk {
+QLIST_ENTRY(Chunk) list;
+Object *obj;
+} Chunk;
+
+static struct QemuMutex reclaimer_lock;
+static QLIST_HEAD(rcl, Chunk) reclaimer_list;
+
+void qemu_reclaimer_enqueue(Object *obj)
+{
+Chunk *r = g_malloc0(sizeof(Chunk));
+r-obj = obj;
+qemu_mutex_lock(reclaimer_lock);
+QLIST_INSERT_HEAD_RCU(reclaimer_list, r, list);
+qemu_mutex_unlock(reclaimer_lock);
+}
+
+void qemu_device_reclaimer(void)
+{
+Chunk *cur, *next;
+
+QLIST_FOREACH_SAFE(cur, reclaimer_list, list, next) {
+QLIST_REMOVE(cur, list);
+object_finalize(cur-obj);
+g_free(cur);
+}
+}
-- 
1.7.4.4




[Qemu-devel] vga-pci and MMIO BAR

2012-07-24 Thread Benjamin Herrenschmidt
Hi folks !

Would there be any objection to adding a second MMIO BAR to qemu-vga
which mirrors the bochs magic VBE ports ?

Support for IO space is optional in PCIe and can be problematic on some
architectures, it would be nice to be able to program the card entirely
using mmio.

Once done, I'd like to look into doing a qemudrmfb similar to the cirrus
one that pretty much gives you generic KMS support (with RandR) on top
of vga-pci. This would have the advantage of potentially lifting the
pitch and size limitations that plague cirrus.

Cheers,
Ben.





Re: [Qemu-devel] [PATCH v4 5/6] qapi: convert sendkey

2012-07-24 Thread Amos Kong


- Original Message -
 On Thu,  5 Jul 2012 20:48:44 +0800
 Amos Kong ak...@redhat.com wrote:
 
  Convert 'sendkey' to use QAPI. do_sendkey() depends on some
  variables/functions in monitor.c, so reserve qmp_sendkey()
  to monitor.c
  
  key_defs[] in console.h is the mapping of key name to keycode,
  Keys' index in the enmu and key_defs[] is same.
  
  'send-key' of QMP doesn't support key in hexadecimal format.
  
  Signed-off-by: Amos Kong ak...@redhat.com
  ---
   console.h|  152 ++
   hmp-commands.hx  |2 +-
   hmp.c|   64 +++
   hmp.h|1 +
   monitor.c|  239
   ++
   qapi-schema.json |   46 +++
   qmp-commands.hx  |   28 +++
   7 files changed, 317 insertions(+), 215 deletions(-)

...

  diff --git a/qapi-schema.json b/qapi-schema.json
  index 3b6e346..08e51c6 100644
  --- a/qapi-schema.json
  +++ b/qapi-schema.json
  @@ -1862,3 +1862,49 @@
   # Since: 0.14.0
   ##
   { 'command': 'netdev_del', 'data': {'id': 'str'} }
  +
  +##
  +# @KeyCodes:
 
 s/KeyCodes/KeyCode


'KeyCode' is not an available variable name.

| ./qapi-types.h:471: error: conflicting types for ‘KeyCode’
| /usr/include/X11/X.h:108: note: previous declaration of ‘KeyCode’ was here

How about 'CodeOfKey'?

  +#
  +# An enumeration of key name.
  +#
  +# This is used by the send-key command.
  +#
  +# Since: 1.2
  +##
  +{ 'enum': 'KeyCodes',
  +  'data': [ 'shift', 'shift_r', 'alt', 'alt_r', 'altgr',
  'altgr_r', 'ctrl',
  +'ctrl_r', 'menu', 'esc', '1', '2', '3', '4', '5', '6',
  '7', '8',
  +'9', '0', 'minus', 'equal', 'backspace', 'tab', 'q',
  'w', 'e',
  +'r', 't', 'y', 'u', 'i', 'o', 'p', 'bracket_left',
  'bracket_right',
  +'ret', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l',
  'semicolon',
  +'apostrophe', 'grave_accent', 'backslash', 'z', 'x',
  'c', 'v', 'b',
  +'n', 'm', 'comma', 'dot', 'slash', 'asterisk', 'spc',
  'caps_lock',
  +'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9',
  'f10',
  +'num_lock', 'scroll_lock', 'kp_divide', 'kp_multiply',
  +'kp_subtract', 'kp_add', 'kp_enter', 'kp_decimal',
  'sysrq', 'kp_0',
  +'kp_1', 'kp_2', 'kp_3', 'kp_4', 'kp_5', 'kp_6',
  'kp_7', 'kp_8',
  +'kp_9', 'less', 'f11', 'f12', 'print', 'home', 'pgup',
  'pgdn', 'end',
  +'left', 'up', 'down', 'right', 'insert', 'delete',
  'stop', 'again',
  +'props', 'undo', 'front', 'copy', 'open', 'paste',
  'find', 'cut',
  + 'lf', 'help', 'meta_l', 'meta_r', 'compose' ] }



[Qemu-devel] [PATCH v3 0/2] GlusterFS support in QEMU - v3

2012-07-24 Thread Bharata B Rao
Hi,

This is the v3 of the patchset to support GlusterFS backend from QEMU.

Apart from cleanups, the major change in this version is to expose all
the gluster configuration options to QEMU user. With this, the gluster
specification looks like this:

-drive file=gluster:server:[port]:[transport]:volname:image

- Here 'gluster' is the protocol.
- 'server' specifies the server where the volume file specification for
  the given volume resides.
- 'port' is the port number on which gluster management daemon (glusterd) is
   listening. This is optional and if not specified, QEMU will send 0 which
   will make libgfapi to use the default port.
- 'transport' specifies the transport used to connect to glusterd. This is
  optional and if not specified, socket transport is used.
- 'volname' is the name of the gluster volume which contains the VM image.
- 'image' is the path to the actual VM image in the gluster volume.

Eg 1: -drive file=gluster:server1:0:socket:test:/image
Eg 2: -drive file=gluster:server1:::test:/image

As I noted during discussions over v2 post, I have gone with colon(:) based
specification. Given that this is anyway going to change with -blockdev, I
would like to go with this unless people strongly favour the URI based
specification.

Changes in v3
-
- New specification to expose all gluster options to QEMU user.
- Added support for bdrv_aio_cancel(), but not really sure how to test
  this.
- Many cleanups based on Stefan Hajnoczi's reveiw comments.

v2
--
http://lists.nongnu.org/archive/html/qemu-devel/2012-07/msg02718.html

v1
--
http://lists.nongnu.org/archive/html/qemu-devel/2012-06/msg01745.html

Regards,
Bharata.




[Qemu-devel] [PATCH v3 1/2] qemu: Add a config option for GlusterFS as block backend

2012-07-24 Thread Bharata B Rao
qemu: Add a config option for GlusterFS as block backend

From: Bharata B Rao bhar...@linux.vnet.ibm.com

GlusterFS support in QEMU depends on libgfapi, libgfrpc and
libgfxdr provided by GlusterFS.

Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
---

 configure |   34 ++
 1 files changed, 34 insertions(+), 0 deletions(-)


diff --git a/configure b/configure
index 500fe24..03547b9 100755
--- a/configure
+++ b/configure
@@ -824,6 +824,10 @@ for opt do
   ;;
   --disable-guest-agent) guest_agent=no
   ;;
+  --disable-glusterfs) glusterfs=no
+  ;;
+  --enable-glusterfs) glusterfs=yes
+  ;;
   *) echo ERROR: unknown option $opt; show_help=yes
   ;;
   esac
@@ -1110,6 +1114,8 @@ echo   --disable-guest-agentdisable building of the 
QEMU Guest Agent
 echo   --enable-guest-agent enable building of the QEMU Guest Agent
 echo   --with-coroutine=BACKEND coroutine backend. Supported options:
 echogthread, ucontext, sigaltstack, windows
+echo   --enable-glusterfs   enable GlusterFS backend
+echo   --disable-glusterfs  disable GlusterFS backend
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2259,6 +2265,29 @@ EOF
   fi
 fi
 
+##
+# glusterfs probe
+if test $glusterfs != no ; then
+  cat  $TMPC EOF
+#include glusterfs/api/glfs.h
+int main(void) {
+(void) glfs_new(volume);
+return 0;
+}
+EOF
+  glusterfs_libs=-lgfapi -lgfrpc -lgfxdr
+  if compile_prog  $glusterfs_libs ; then
+glusterfs=yes
+libs_tools=$glusterfs_libs $libs_tools
+libs_softmmu=$glusterfs_libs $libs_softmmu
+  else
+if test $glusterfs = yes ; then
+  feature_not_found GlusterFS backend support
+fi
+glusterfs=no
+  fi
+fi
+
 #
 # Check for xxxat() functions when we are building linux-user
 # emulator.  This is done because older glibc versions don't
@@ -3055,6 +3084,7 @@ echo OpenGL support$opengl
 echo libiscsi support  $libiscsi
 echo build guest agent $guest_agent
 echo coroutine backend $coroutine_backend
+echo GlusterFS support $glusterfs
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -3384,6 +3414,10 @@ if test $has_environ = yes ; then
   echo CONFIG_HAS_ENVIRON=y  $config_host_mak
 fi
 
+if test $glusterfs = yes ; then
+  echo CONFIG_GLUSTERFS=y  $config_host_mak
+fi
+
 # USB host support
 case $usb in
 linux)




[Qemu-devel] [PATCH v3 2/2] block: Support GlusterFS as a QEMU block backend

2012-07-24 Thread Bharata B Rao
block: Support GlusterFS as a QEMU block backend.

From: Bharata B Rao bhar...@linux.vnet.ibm.com

This patch adds gluster as the new block backend in QEMU. This gives
QEMU the ability to boot VM images from gluster volumes. Its already
possible to boot from VM images on gluster volumes, but this patchset
provides the ability to boot VM images from gluster volumes by by-passing
the FUSE layer in gluster. In case the image is present on the local
system, it is possible to even bypass client and server translator and
hence the RPC overhead.

VM Image on gluster volume is specified like this:

-drive file=gluster:server:[port]:[transport]:volname:image

- Here 'gluster' is the protocol.
- 'server' specifies the server where the volume file specification for
  the given volume resides.
- 'port' is the port number on which gluster management daemon (glusterd) is
   listening. This is optional and if not specified, QEMU will send 0 which
   will make libgfapi to use the default port.
- 'transport' specifies the transport used to connect to glusterd. This is
  optional and if not specified, socket transport is used.
- 'volname' is the name of the gluster volume which contains the VM image.
- 'image' is the path to the actual VM image in the gluster volume.

Eg 1: -drive file=gluster:server1:0:socket:test:/image
Eg 2: -drive file=gluster:server1:::test:/image

Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
---

 block/Makefile.objs |1 
 block/gluster.c |  484 +++
 2 files changed, 485 insertions(+), 0 deletions(-)
 create mode 100644 block/gluster.c


diff --git a/block/Makefile.objs b/block/Makefile.objs
index b5754d3..a1ae67f 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -9,3 +9,4 @@ block-obj-$(CONFIG_POSIX) += raw-posix.o
 block-obj-$(CONFIG_LIBISCSI) += iscsi.o
 block-obj-$(CONFIG_CURL) += curl.o
 block-obj-$(CONFIG_RBD) += rbd.o
+block-obj-$(CONFIG_GLUSTERFS) += gluster.o
diff --git a/block/gluster.c b/block/gluster.c
new file mode 100644
index 000..b27971b
--- /dev/null
+++ b/block/gluster.c
@@ -0,0 +1,484 @@
+/*
+ * GlusterFS backend for QEMU
+ *
+ * (AIO implementation is derived from block/rbd.c)
+ *
+ * Copyright (C) 2012 Bharata B Rao bhar...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version. See the COPYING file in the top-level
+ * directory.
+ */
+#include block_int.h
+#include glusterfs/api/glfs.h
+
+typedef struct GlusterAIOCB {
+BlockDriverAIOCB common;
+bool canceled;
+int64_t size;
+int ret;
+} GlusterAIOCB;
+
+typedef struct BDRVGlusterState {
+struct glfs *glfs;
+int fds[2];
+struct glfs_fd *fd;
+int qemu_aio_count;
+} BDRVGlusterState;
+
+#define GLUSTER_FD_READ 0
+#define GLUSTER_FD_WRITE 1
+
+typedef enum {
+GOPT_PROTOCOL,
+GOPT_SERVER,
+GOPT_PORT,
+GOPT_TRANSPORT,
+GOPT_VOLNAME,
+GOPT_IMAGE,
+
+GOPT_LAST,
+} GlusterOptsEnum;
+
+struct GlusterOpts {
+bool optional;
+char defval[10];
+char *value;
+} GlusterOpts[] = {
+{false, , NULL },
+{false, , NULL },
+{true, 0, NULL },
+{true, socket, NULL },
+{false, , NULL },
+{false, , NULL },
+};
+
+static void qemu_gluster_opts_free(void)
+{
+int i;
+
+for (i = 0; i  GOPT_LAST; i++) {
+g_free(GlusterOpts[i].value);
+/* Prepare GlusterOpts to parse the next gluster drive (if any) */
+GlusterOpts[i].value = NULL;
+}
+}
+
+/*
+ * file=protocol:server:[port]:[transport]:volname:image
+ */
+static int qemu_gluster_parsename(const char *filename)
+{
+char *p, *q, *r;
+int ret = -EINVAL;
+int i;
+
+p = q = r = g_strdup(filename);
+for (i = 0; i  GOPT_LAST; i++) {
+q = p;
+p = strchr(p, ':');
+if (!p) {
+goto out;
+}
+
+if (p == q) {
+if (GlusterOpts[i].optional) {
+GlusterOpts[i].value = g_strdup(GlusterOpts[i].defval);
+p++;
+continue;
+} else {
+goto out;
+}
+}
+*p++ = '\0';
+GlusterOpts[i].value = g_strdup(q);
+}
+out:
+if (i == GOPT_LAST-1  strlen(q)) {
+GlusterOpts[i].value = g_strdup(q);
+ret = 0;
+}
+g_free(r);
+return ret;
+}
+
+static struct glfs *qemu_gluster_init(const char *filename)
+{
+struct glfs *glfs = NULL;
+int ret;
+int port;
+
+ret = qemu_gluster_parsename(filename);
+if (ret  0) {
+errno = -ret;
+goto out;
+}
+
+port = strtoul(GlusterOpts[GOPT_PORT].value, NULL, 0);
+if (port  0) {
+goto out;
+}
+
+glfs = glfs_new(GlusterOpts[GOPT_VOLNAME].value);
+if (!glfs) {
+goto out;
+}
+
+ret = glfs_set_volfile_server(glfs, GlusterOpts[GOPT_TRANSPORT].value,
+GlusterOpts[GOPT_SERVER].value, port);
+if (ret  0) {
+goto 

[Qemu-devel] [Bug 1028260] [NEW] ARM: stellaris lm3s6965evb machine model broken

2012-07-24 Thread Peter Crosthwaite
Public bug reported:

The Stellaris lm3s6965evb Machine model is broken:

qemu-system-arm -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type show copying
and show warranty for details.
This GDB was configured as x86_64-linux-gnu.
For bug reporting instructions, please see:
http://www.gnu.org/software/gdb/bugs/...
Reading symbols from 
/home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm...done.
(gdb) r
Starting program: 
/home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm
 -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
[Thread debugging using libthread_db enabled]
warning: no loadable sections found in added symbol-file in-memory
[New Thread 0x763fc700 (LWP 15156)]
qemu-system-arm: /home/peterc/Petalogix/Internal/plgx_src/qemu/hw/qdev.c:309: 
qdev_get_gpio_in: Assertion `n = 0  n  dev-num_gpio_in' failed.

Program received signal SIGABRT, Aborted.
0x006f4a2b in raise (sig=value optimised out) at 
../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
42  ../nptl/sysdeps/unix/sysv/linux/pt-raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/pt-raise.c
(gdb) bt
#0  0x006f4a2b in raise (sig=value optimised out)
at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
#1  0x007089a0 in abort ()
#2  0x00702c15 in __assert_fail ()
#3  0x00463ffa in qdev_get_gpio_in ()
#4  0x00588f94 in armv7m_init ()
#5  0x0060c62a in stellaris_init ()
#6  0x0060cc4e in lm3s6965evb_init ()
#7  0x004fdb11 in main ()
(gdb) 

Bisection points at this commit:

commit 1e8cae4dfea2bcc91d3820dcf4f9284e7b0abb28
Author: Peter Maydell peter.mayd...@linaro.org
Date:   Wed May 2 16:49:42 2012 +

hw/armv7m_nvic: Make the NVIC a freestanding class

Rearrange the GIC and NVIC so both are straightforward
subclasses of a common class, rather than having the NVIC
source file textually include arm_gic.c.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1028260

Title:
  ARM: stellaris lm3s6965evb machine model broken

Status in QEMU:
  New

Bug description:
  The Stellaris lm3s6965evb Machine model is broken:

  qemu-system-arm -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
  GNU gdb (GDB) 7.1-ubuntu
  Copyright (C) 2010 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.  Type show copying
  and show warranty for details.
  This GDB was configured as x86_64-linux-gnu.
  For bug reporting instructions, please see:
  http://www.gnu.org/software/gdb/bugs/...
  Reading symbols from 
/home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm...done.
  (gdb) r
  Starting program: 
/home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm
 -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
  [Thread debugging using libthread_db enabled]
  warning: no loadable sections found in added symbol-file in-memory
  [New Thread 0x763fc700 (LWP 15156)]
  qemu-system-arm: /home/peterc/Petalogix/Internal/plgx_src/qemu/hw/qdev.c:309: 
qdev_get_gpio_in: Assertion `n = 0  n  dev-num_gpio_in' failed.

  Program received signal SIGABRT, Aborted.
  0x006f4a2b in raise (sig=value optimised out) at 
../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
  42../nptl/sysdeps/unix/sysv/linux/pt-raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/pt-raise.c
  (gdb) bt
  #0  0x006f4a2b in raise (sig=value optimised out)
  at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
  #1  0x007089a0 in abort ()
  #2  0x00702c15 in __assert_fail ()
  #3  0x00463ffa in qdev_get_gpio_in ()
  #4  0x00588f94 in armv7m_init ()
  #5  0x0060c62a in stellaris_init ()
  #6  0x0060cc4e in lm3s6965evb_init ()
  #7  0x004fdb11 in main ()
  (gdb) 

  Bisection points at this commit:

  commit 1e8cae4dfea2bcc91d3820dcf4f9284e7b0abb28
  Author: Peter Maydell peter.mayd...@linaro.org
  Date:   Wed May 2 16:49:42 2012 +

  hw/armv7m_nvic: Make the NVIC a freestanding class
  
  Rearrange the GIC and NVIC so both are straightforward
 

Re: [Qemu-devel] [Bug 1028260] [NEW] ARM: stellaris lm3s6965evb machine model broken

2012-07-24 Thread Peter Crosthwaite
cc relevant maintainers (PMM and PB).

On Tue, Jul 24, 2012 at 3:58 PM, Peter Crosthwaite
peter.crosthwa...@petalogix.com wrote:
 Public bug reported:

 The Stellaris lm3s6965evb Machine model is broken:

 qemu-system-arm -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
 GNU gdb (GDB) 7.1-ubuntu
 Copyright (C) 2010 Free Software Foundation, Inc.
 License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
 This is free software: you are free to change and redistribute it.
 There is NO WARRANTY, to the extent permitted by law.  Type show copying
 and show warranty for details.
 This GDB was configured as x86_64-linux-gnu.
 For bug reporting instructions, please see:
 http://www.gnu.org/software/gdb/bugs/...
 Reading symbols from 
 /home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm...done.
 (gdb) r
 Starting program: 
 /home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm
  -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
 [Thread debugging using libthread_db enabled]
 warning: no loadable sections found in added symbol-file in-memory
 [New Thread 0x763fc700 (LWP 15156)]
 qemu-system-arm: /home/peterc/Petalogix/Internal/plgx_src/qemu/hw/qdev.c:309: 
 qdev_get_gpio_in: Assertion `n = 0  n  dev-num_gpio_in' failed.

 Program received signal SIGABRT, Aborted.
 0x006f4a2b in raise (sig=value optimised out) at 
 ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
 42  ../nptl/sysdeps/unix/sysv/linux/pt-raise.c: No such file or directory.
 in ../nptl/sysdeps/unix/sysv/linux/pt-raise.c
 (gdb) bt
 #0  0x006f4a2b in raise (sig=value optimised out)
 at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
 #1  0x007089a0 in abort ()
 #2  0x00702c15 in __assert_fail ()
 #3  0x00463ffa in qdev_get_gpio_in ()
 #4  0x00588f94 in armv7m_init ()
 #5  0x0060c62a in stellaris_init ()
 #6  0x0060cc4e in lm3s6965evb_init ()
 #7  0x004fdb11 in main ()
 (gdb)

 Bisection points at this commit:

 commit 1e8cae4dfea2bcc91d3820dcf4f9284e7b0abb28
 Author: Peter Maydell peter.mayd...@linaro.org
 Date:   Wed May 2 16:49:42 2012 +

 hw/armv7m_nvic: Make the NVIC a freestanding class

 Rearrange the GIC and NVIC so both are straightforward
 subclasses of a common class, rather than having the NVIC
 source file textually include arm_gic.c.

 Signed-off-by: Peter Maydell peter.mayd...@linaro.org

 ** Affects: qemu
  Importance: Undecided
  Status: New

 --
 You received this bug notification because you are a member of qemu-
 devel-ml, which is subscribed to QEMU.
 https://bugs.launchpad.net/bugs/1028260

 Title:
   ARM: stellaris lm3s6965evb machine model broken

 Status in QEMU:
   New

 Bug description:
   The Stellaris lm3s6965evb Machine model is broken:

   qemu-system-arm -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
   GNU gdb (GDB) 7.1-ubuntu
   Copyright (C) 2010 Free Software Foundation, Inc.
   License GPLv3+: GNU GPL version 3 or later 
 http://gnu.org/licenses/gpl.html
   This is free software: you are free to change and redistribute it.
   There is NO WARRANTY, to the extent permitted by law.  Type show copying
   and show warranty for details.
   This GDB was configured as x86_64-linux-gnu.
   For bug reporting instructions, please see:
   http://www.gnu.org/software/gdb/bugs/...
   Reading symbols from 
 /home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm...done.
   (gdb) r
   Starting program: 
 /home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm
  -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
   [Thread debugging using libthread_db enabled]
   warning: no loadable sections found in added symbol-file in-memory
   [New Thread 0x763fc700 (LWP 15156)]
   qemu-system-arm: 
 /home/peterc/Petalogix/Internal/plgx_src/qemu/hw/qdev.c:309: 
 qdev_get_gpio_in: Assertion `n = 0  n  dev-num_gpio_in' failed.

   Program received signal SIGABRT, Aborted.
   0x006f4a2b in raise (sig=value optimised out) at 
 ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
   42../nptl/sysdeps/unix/sysv/linux/pt-raise.c: No such file or directory.
 in ../nptl/sysdeps/unix/sysv/linux/pt-raise.c
   (gdb) bt
   #0  0x006f4a2b in raise (sig=value optimised out)
   at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
   #1  0x007089a0 in abort ()
   #2  0x00702c15 in __assert_fail ()
   #3  0x00463ffa in qdev_get_gpio_in ()
   #4  0x00588f94 in armv7m_init ()
   #5  0x0060c62a in stellaris_init ()
   #6  0x0060cc4e in lm3s6965evb_init ()
   #7  0x004fdb11 in main ()
   (gdb)

   Bisection points at this commit:

   commit 

[Qemu-devel] [Bug 1028260] Re: ARM: stellaris lm3s6965evb machine model broken

2012-07-24 Thread Peter Crosthwaite
** Attachment added: Test vector to replicate bug
   
https://bugs.launchpad.net/qemu/+bug/1028260/+attachment/3233691/+files/stellaris-test.tar

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1028260

Title:
  ARM: stellaris lm3s6965evb machine model broken

Status in QEMU:
  New

Bug description:
  The Stellaris lm3s6965evb Machine model is broken:

  qemu-system-arm -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
  GNU gdb (GDB) 7.1-ubuntu
  Copyright (C) 2010 Free Software Foundation, Inc.
  License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
  This is free software: you are free to change and redistribute it.
  There is NO WARRANTY, to the extent permitted by law.  Type show copying
  and show warranty for details.
  This GDB was configured as x86_64-linux-gnu.
  For bug reporting instructions, please see:
  http://www.gnu.org/software/gdb/bugs/...
  Reading symbols from 
/home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm...done.
  (gdb) r
  Starting program: 
/home/peterc/Petalogix/Internal/plgx_install/qemu-upstream-regression/petalinux-vx.x/tools/linux-i386/petalogix/bin/qemu-system-arm
 -M lm3s6965evb -kernel qs_ek-lm3s6965.bin
  [Thread debugging using libthread_db enabled]
  warning: no loadable sections found in added symbol-file in-memory
  [New Thread 0x763fc700 (LWP 15156)]
  qemu-system-arm: /home/peterc/Petalogix/Internal/plgx_src/qemu/hw/qdev.c:309: 
qdev_get_gpio_in: Assertion `n = 0  n  dev-num_gpio_in' failed.

  Program received signal SIGABRT, Aborted.
  0x006f4a2b in raise (sig=value optimised out) at 
../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
  42../nptl/sysdeps/unix/sysv/linux/pt-raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/pt-raise.c
  (gdb) bt
  #0  0x006f4a2b in raise (sig=value optimised out)
  at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:42
  #1  0x007089a0 in abort ()
  #2  0x00702c15 in __assert_fail ()
  #3  0x00463ffa in qdev_get_gpio_in ()
  #4  0x00588f94 in armv7m_init ()
  #5  0x0060c62a in stellaris_init ()
  #6  0x0060cc4e in lm3s6965evb_init ()
  #7  0x004fdb11 in main ()
  (gdb) 

  Bisection points at this commit:

  commit 1e8cae4dfea2bcc91d3820dcf4f9284e7b0abb28
  Author: Peter Maydell peter.mayd...@linaro.org
  Date:   Wed May 2 16:49:42 2012 +

  hw/armv7m_nvic: Make the NVIC a freestanding class
  
  Rearrange the GIC and NVIC so both are straightforward
  subclasses of a common class, rather than having the NVIC
  source file textually include arm_gic.c.
  
  Signed-off-by: Peter Maydell peter.mayd...@linaro.org

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1028260/+subscriptions



Re: [Qemu-devel] [PATCH 13/22] Add migration capabilities

2012-07-24 Thread Orit Wasserman
On 07/23/2012 09:23 PM, Luiz Capitulino wrote:
 On Fri, 13 Jul 2012 09:23:35 +0200
 Juan Quintela quint...@redhat.com wrote:
 
 From: Orit Wasserman owass...@redhat.com

 Add migration capabilities that can be queried by the management.
 The management can query the source QEMU and the destination QEMU in order to
 verify both support some migration capability (currently only XBZRLE).
 The management can enable a capability for the next migration by using
 migrate_set_parameter command.
 
 Please, split this into one command per-patch. Otherwise it's difficult to
 review.
 
Sure.
 Have libvirt folks acked this approach btw? It looks fine to me, but we need
 their ack too.
 
 More comments below.
 

 Signed-off-by: Orit Wasserman owass...@redhat.com
 Signed-off-by: Juan Quintela quint...@redhat.com
 ---
  hmp-commands.hx  |   16 
  hmp.c|   64 
  hmp.h|2 ++
  migration.c  |   72 
 --
  migration.h  |2 ++
  monitor.c|7 ++
  qapi-schema.json |   53 ++--
  qmp-commands.hx  |   71 
 ++---
  8 files changed, 280 insertions(+), 7 deletions(-)

 diff --git a/hmp-commands.hx b/hmp-commands.hx
 index f5d9d91..9245bef 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
 @@ -861,6 +861,20 @@ Set maximum tolerated downtime (in seconds) for 
 migration.
  ETEXI

  {
 +.name   = migrate_set_parameter,
 +.args_type  = capability:s,state:b,
 +.params = ,
 
 Please, fill in params.
ok
 
 +.help   = Enable/Disable the usage of a capability for 
 migration,
 +.mhandler.cmd = hmp_migrate_set_parameter,
 +},
 +
 +STEXI
 +@item migrate_set_parameter @var{capability} @var{state}
 +@findex migrate_set_parameter
 +Enable/Disable the usage of a capability @var{capability} for migration.
 +ETEXI
 +
 +{
  .name   = client_migrate_info,
  .args_type  = 
 protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?,
  .params = protocol hostname port tls-port cert-subject,
 @@ -1419,6 +1433,8 @@ show CPU statistics
  show user network stack connection states
  @item info migrate
  show migration status
 +@item info migration_capabilities
 +show migration capabilities
  @item info balloon
  show balloon information
  @item info qtree
 diff --git a/hmp.c b/hmp.c
 index 4c6d4ae..b0440e6 100644
 --- a/hmp.c
 +++ b/hmp.c
 @@ -131,9 +131,19 @@ void hmp_info_mice(Monitor *mon)
  void hmp_info_migrate(Monitor *mon)
  {
  MigrationInfo *info;
 +MigrationCapabilityInfoList *cap;

  info = qmp_query_migrate(NULL);

 +if (info-has_capabilities  info-capabilities) {
 +monitor_printf(mon, capabilities: );
 +for (cap = info-capabilities; cap; cap = cap-next) {
 +monitor_printf(mon, %s: %s ,
 +   
 MigrationCapability_lookup[cap-value-capability],
 +   cap-value-state ? on : off);
 +}
 +monitor_printf(mon, \n);
 
 Why is this is needed? Isn't info migration-capabilities good enough?
 Besides, info migrate should only contain information about current migration
 process...
The reason we introduced capabilities is that xbzrle needs for both source and 
destination QEMU
to be able to handle it. Even if both side support xbzrle the user may decide 
not to use it.
User that wants to use xbzrle needs to check that both sides have support for 
it (using info capabilities) , than 
enable it in both sides (using migrate-set-parameter/s commands). This is a 
parameter for the current migration.
So the user needs to know if xbzrle was enabled or disabled for the current 
migration, this code displays it.

some day when there will be better migration protocol, feature negotiations can 
be part of it ...
 
 +}
  if (info-has_status) {
  monitor_printf(mon, Migration status: %s\n, info-status);
  }
 @@ -161,6 +171,25 @@ void hmp_info_migrate(Monitor *mon)
  qapi_free_MigrationInfo(info);
  }

 +void hmp_info_migration_capabilities(Monitor *mon)
 +{
 +MigrationCapabilityInfoList *caps_list, *cap;
 +
 +caps_list = qmp_query_migration_capabilities(NULL);
 +if (!caps_list) {
 +monitor_printf(mon, No migration capabilities found\n);
 +return;
 +}
 +
 +for (cap = caps_list; cap; cap = cap-next) {
 +monitor_printf(mon, %s: %s ,
 +   MigrationCapability_lookup[cap-value-capability],
 +   cap-value-state ? on : off);
 +}
 +
 +qapi_free_MigrationCapabilityInfoList(caps_list);
 +}
 +
  void hmp_info_cpus(Monitor *mon)
  {
  CpuInfoList *cpu_list, *cpu;
 @@ -735,6 +764,41 @@ void hmp_migrate_set_speed(Monitor *mon, const QDict 
 *qdict)
  qmp_migrate_set_speed(value, NULL);
  }

 +void 

Re: [Qemu-devel] [PATCH 21/22] Add XBZRLE statistics

2012-07-24 Thread Orit Wasserman
On 07/23/2012 10:33 PM, Luiz Capitulino wrote:
 On Fri, 13 Jul 2012 09:23:43 +0200
 Juan Quintela quint...@redhat.com wrote:
 
 From: Orit Wasserman owass...@redhat.com

 Signed-off-by: Benoit Hudzia benoit.hud...@sap.com
 Signed-off-by: Petter Svard pett...@cs.umu.se
 Signed-off-by: Aidan Shribman aidan.shrib...@sap.com
 Signed-off-by: Orit Wasserman owass...@redhat.com
 Signed-off-by: Juan Quintela quint...@redhat.com
 ---
  arch_init.c  |   66 
 ++
  hmp.c|   13 +++
  migration.c  |   49 
  migration.h  |9 
  qapi-schema.json |   37 +-
  qmp-commands.hx  |   35 -
  6 files changed, 203 insertions(+), 6 deletions(-)

 diff --git a/arch_init.c b/arch_init.c
 index d972d84..ab3fb2c 100644
 --- a/arch_init.c
 +++ b/arch_init.c
 @@ -202,6 +202,64 @@ int64_t xbzrle_cache_resize(int64_t new_size)
  return pow2floor(new_size);
  }

 +/* accounting for migration statistics */
 +typedef struct AccountingInfo {
 +uint64_t dup_pages;
 +uint64_t norm_pages;
 +uint64_t xbzrle_bytes;
 +uint64_t xbzrle_pages;
 +uint64_t xbzrle_cache_miss;
 +uint64_t iterations;
 +uint64_t xbzrle_overflows;
 +} AccountingInfo;
 +
 +static AccountingInfo acct_info;
 +
 +static void acct_clear(void)
 +{
 +memset(acct_info, 0, sizeof(acct_info));
 +}
 +
 +uint64_t dup_mig_bytes_transferred(void)
 +{
 +return acct_info.dup_pages * TARGET_PAGE_SIZE;
 +}
 +
 +uint64_t dup_mig_pages_transferred(void)
 +{
 +return acct_info.dup_pages;
 +}
 +
 +uint64_t norm_mig_bytes_transferred(void)
 +{
 +return acct_info.norm_pages * TARGET_PAGE_SIZE;
 +}
 +
 +uint64_t norm_mig_pages_transferred(void)
 +{
 +return acct_info.norm_pages;
 +}
 +
 +uint64_t xbzrle_mig_bytes_transferred(void)
 +{
 +return acct_info.xbzrle_bytes;
 +}
 +
 +uint64_t xbzrle_mig_pages_transferred(void)
 +{
 +return acct_info.xbzrle_pages;
 +}
 +
 +uint64_t xbzrle_mig_pages_cache_miss(void)
 +{
 +return acct_info.xbzrle_cache_miss;
 +}
 +
 +uint64_t xbzrle_mig_pages_overflow(void)
 +{
 +return acct_info.xbzrle_overflows;
 +}
 +
  static void save_block_hdr(QEMUFile *f, RAMBlock *block, ram_addr_t offset,
  int cont, int flag)
  {
 @@ -230,6 +288,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
 *current_data,
  if (!cache_is_cached(XBZRLE.cache, current_addr)) {
  cache_insert(XBZRLE.cache, current_addr,
   g_memdup(current_data, TARGET_PAGE_SIZE));
 +acct_info.xbzrle_cache_miss++;
  return -1;
  }

 @@ -244,6 +303,7 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
 *current_data,
  return 0;
  } else if (encoded_len == -1) {
  DPRINTF(Overflow\n);
 +acct_info.xbzrle_overflows++;
  /* update data in the cache */
  memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
  return -1;
 @@ -263,7 +323,9 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t 
 *current_data,
  qemu_put_byte(f, hdr.xh_flags);
  qemu_put_be16(f, hdr.xh_len);
  qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
 +acct_info.xbzrle_pages++;
  bytes_sent = encoded_len + sizeof(hdr);
 +acct_info.xbzrle_bytes += bytes_sent;

  return bytes_sent;
  }
 @@ -303,6 +365,7 @@ static int ram_save_block(QEMUFile *f)
  p = memory_region_get_ram_ptr(mr) + offset;

  if (is_dup_page(p)) {
 +acct_info.dup_pages++;
  save_block_hdr(f, block, offset, cont, 
 RAM_SAVE_FLAG_COMPRESS);
  qemu_put_byte(f, *p);
  bytes_sent = 1;
 @@ -318,6 +381,7 @@ static int ram_save_block(QEMUFile *f)
  save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
  qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
  bytes_sent = TARGET_PAGE_SIZE;
 +acct_info.norm_pages++;
  }

  /* if page is unmodified, continue to the next */
 @@ -437,6 +501,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
  return -1;
  }
  XBZRLE.encoded_buf = g_malloc0(TARGET_PAGE_SIZE);
 +acct_clear();
  }

  QLIST_FOREACH(block, ram_list.blocks, next) {
 @@ -484,6 +549,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
  break;
  }
  bytes_transferred += bytes_sent;
 +acct_info.iterations++;
  /* we want to check in the 1st loop, just in case it was the 1st 
 time
 and we had to sync the dirty bitmap.
 qemu_get_clock_ns() is a bit expensive, so we only check each 
 some
 diff --git a/hmp.c b/hmp.c
 index 99ad00a..0d7333b 100644
 --- a/hmp.c
 +++ b/hmp.c
 @@ -168,6 +168,19 @@ void hmp_info_migrate(Monitor *mon)
 info-disk-total  10);
  }

 +if 

Re: [Qemu-devel] [PATCH 16/16] hub: add the support for hub own flow control

2012-07-24 Thread Paolo Bonzini
Il 24/07/2012 00:27, Laszlo Ersek ha scritto:
 This seems to consolidate net_hub_receive_iov()'s retval with that of
 net_hub_receive(), but may I ask why it used to be calculated differently?

Because until this patch was introduced, net/hub.c had a TODO about the
return values of net_hub_receive_*().  Probably this patch could be
squashed earlier in the series, but it's not paramount.

Paolo




[Qemu-devel] [PATCH 0/7v3] s390: sclp patch set

2012-07-24 Thread Christian Borntraeger
This patch-set improves the Service-Call Logical Processor support for s390.
This version addresses comments from Blueswirl and Andreas Färber.

Patch 1 is a bugfix for the current code, dealing with error and condition
code handling. Patch 2 introduces a new file under target-s390 which will
provide floating interrupt support.
Patch 3 adds/changes some base SCLP support. Patch 4 adds code
to support the SCLP commands Write Event Mask, Write Event Data, and
Read Event Data. Patch 5 and 6 add code to implement the commands for the
particular SCLP events Signal Quiesce (system_powerdown), and ASCII Console
data.
Patch 7 (s390: make sclp ascii console the default) is currently optional
as it requires a kernel fix in the guest
(http://git.kernel.org/?p=virt/kvm/kvm.git;a=commit;h=cd1834591fe9564720ac4b0193bf1c790fe89f0d
KVM: s390: Perform early event mask processing during boot)
For testing patches 6 and 7 on older kernels the kernel command line
console=ttyS1 can be used.

Thanks

Christian Borntraeger (3):
  s390: Fix error handling and condition code of service call
  s390: provide interface for service interrupt/introduce interrupt.c
  s390: make sclp ascii console the default

Heinz Graalfs (4):
  s390: sclp base support
  s390: sclp event support
  s390: sclp signal quiesce support
  s390: sclp ascii console support

 hw/s390-virtio.c   |3 +-
 hw/s390x/Makefile.objs |3 +
 hw/s390x/event-facility.c  |  397 
 hw/s390x/event-facility.h  |  107 
 hw/s390x/sclp.c|  187 +
 hw/s390x/sclp.h|  123 ++
 hw/s390x/sclpconsole.c |  323 +++
 hw/s390x/sclpquiesce.c |  112 +
 target-s390x/Makefile.objs |2 +-
 target-s390x/cpu.h |   17 +--
 target-s390x/interrupt.c   |   29 
 target-s390x/kvm.c |   10 +-
 target-s390x/op_helper.c   |   68 +++-
 vl.c   |   44 +
 14 files changed, 1358 insertions(+), 67 deletions(-)
 create mode 100644 hw/s390x/event-facility.c
 create mode 100644 hw/s390x/event-facility.h
 create mode 100644 hw/s390x/sclp.c
 create mode 100644 hw/s390x/sclp.h
 create mode 100644 hw/s390x/sclpconsole.c
 create mode 100644 hw/s390x/sclpquiesce.c
 create mode 100644 target-s390x/interrupt.c




[Qemu-devel] [PATCH 7/7] s390: make sclp ascii console the default

2012-07-24 Thread Christian Borntraeger
This patch makes the sclp ascii default for S390.

Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
---
 hw/s390-virtio.c |1 -
 vl.c |   44 
 2 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 28e320d..8b48f66 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -341,7 +341,6 @@ static QEMUMachine s390_machine = {
 .no_serial = 1,
 .no_parallel = 1,
 .no_sdcard = 1,
-.use_virtcon = 1,
 .max_cpus = 255,
 .is_default = 1,
 };
diff --git a/vl.c b/vl.c
index 46248b9..7197724 100644
--- a/vl.c
+++ b/vl.c
@@ -168,6 +168,7 @@ int main(int argc, char **argv)
 #define DEFAULT_RAM_SIZE 128
 
 #define MAX_VIRTIO_CONSOLES 1
+#define MAX_SCLP_CONSOLES   1
 
 static const char *data_dir;
 const char *bios_name = NULL;
@@ -195,6 +196,7 @@ int no_quit = 0;
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
+CharDriverState *sclpcon_hds[MAX_SCLP_CONSOLES];
 int win2k_install_hack = 0;
 int usb_enabled = 0;
 int singlestep = 0;
@@ -268,6 +270,7 @@ static int default_floppy = 1;
 static int default_cdrom = 1;
 static int default_sdcard = 1;
 static int default_vga = 1;
+static int default_sclpcon = 1;
 
 static struct {
 const char *driver;
@@ -289,6 +292,7 @@ static struct {
 { .driver = isa-cirrus-vga,   .flag = default_vga   },
 { .driver = vmware-svga,  .flag = default_vga   },
 { .driver = qxl-vga,  .flag = default_vga   },
+{ .driver = sclpconsole,  .flag = default_sclpcon   },
 };
 
 static void res_free(void)
@@ -1935,6 +1939,7 @@ struct device_config {
 DEV_VIRTCON,   /* -virtioconsole */
 DEV_DEBUGCON,  /* -debugcon */
 DEV_GDB,   /* -gdb, -s */
+DEV_SCLPCON,   /* sclp console */
 } type;
 const char *cmdline;
 Location loc;
@@ -2014,6 +2019,36 @@ static int parallel_parse(const char *devname)
 return 0;
 }
 
+static int sclpcon_parse(const char *devname)
+{
+QemuOptsList *device = qemu_find_opts(device);
+static int index = 0;
+char label[32];
+QemuOpts *dev_opts;
+
+if (strcmp(devname, none) == 0)
+return 0;
+if (index == MAX_SCLP_CONSOLES) {
+fprintf(stderr, qemu: too many sclp consoles\n);
+exit(1);
+}
+
+dev_opts = qemu_opts_create(device, NULL, 0, NULL);
+qemu_opt_set(dev_opts, driver, sclpconsole);
+
+snprintf(label, sizeof(label), sclpcon%d, index);
+sclpcon_hds[index] = qemu_chr_new(label, devname, NULL);
+if (!sclpcon_hds[index]) {
+fprintf(stderr, qemu: could not open sclp console '%s': %s\n,
+devname, strerror(errno));
+return -1;
+}
+qemu_opt_set(dev_opts, chardev, label);
+
+index++;
+return 0;
+}
+
 static int virtcon_parse(const char *devname)
 {
 QemuOptsList *device = qemu_find_opts(device);
@@ -3122,6 +3157,7 @@ int main(int argc, char **argv, char **envp)
 default_cdrom = 0;
 default_sdcard = 0;
 default_vga = 0;
+default_sclpcon = 0;
 break;
 case QEMU_OPTION_xen_domid:
 if (!(xen_available())) {
@@ -3303,11 +3339,15 @@ int main(int argc, char **argv, char **envp)
 add_device_config(DEV_PARALLEL, null);
 if (default_serial  default_monitor) {
 add_device_config(DEV_SERIAL, mon:stdio);
+} else if (default_sclpcon  default_monitor) {
+add_device_config(DEV_SCLPCON, mon:stdio);
 } else if (default_virtcon  default_monitor) {
 add_device_config(DEV_VIRTCON, mon:stdio);
 } else {
 if (default_serial)
 add_device_config(DEV_SERIAL, stdio);
+if (default_sclpcon)
+add_device_config(DEV_SCLPCON, stdio);
 if (default_virtcon)
 add_device_config(DEV_VIRTCON, stdio);
 if (default_monitor)
@@ -3320,6 +3360,8 @@ int main(int argc, char **argv, char **envp)
 add_device_config(DEV_PARALLEL, vc:80Cx24C);
 if (default_monitor)
 monitor_parse(vc:80Cx24C, readline);
+if (default_sclpcon)
+add_device_config(DEV_SCLPCON, vc:80Cx24C);
 if (default_virtcon)
 add_device_config(DEV_VIRTCON, vc:80Cx24C);
 }
@@ -3490,6 +3532,8 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 if (foreach_device_config(DEV_PARALLEL, parallel_parse)  0)
 exit(1);
+if (foreach_device_config(DEV_SCLPCON, sclpcon_parse)  0)
+exit(1);
 if (foreach_device_config(DEV_VIRTCON, virtcon_parse)  0)
 exit(1);
 if (foreach_device_config(DEV_DEBUGCON, debugcon_parse)  0)
-- 
1.7.0.1




[Qemu-devel] [PATCH 1/7] s390: Fix error handling and condition code of service call

2012-07-24 Thread Christian Borntraeger
Invalid sccb addresses will cause specification or addressing exception.
Lets add those checks. Furthermore, the good case (cc=0) was incorrect
for KVM, we did not set the CC at all. We now use return codes  0
as program checks and return codes  0 as condition code values.

Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
---
 target-s390x/kvm.c   |5 +++--
 target-s390x/op_helper.c |   27 ++-
 2 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 47008c2..07edf93 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -273,9 +273,10 @@ static int kvm_sclp_service_call(CPUS390XState *env, 
struct kvm_run *run,
 code = env-regs[(ipbh0  0xf0)  4];
 
 r = sclp_service_call(env, sccb, code);
-if (r) {
-setcc(env, 3);
+if (r  0) {
+enter_pgmcheck(env, -r);
 }
+setcc(env, r);
 
 return 0;
 }
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 7b72473..91dd8dc 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -19,6 +19,8 @@
  */
 
 #include cpu.h
+#include memory.h
+#include cputlb.h
 #include dyngen-exec.h
 #include host-utils.h
 #include helper.h
@@ -2366,6 +2368,9 @@ static void ext_interrupt(CPUS390XState *env, int type, 
uint32_t param,
 cpu_inject_ext(env, type, param, param64);
 }
 
+/*
+ * ret  0 indicates program check, ret = 0,1,2,3 - cc
+ */
 int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
 {
 int r = 0;
@@ -2375,10 +2380,12 @@ int sclp_service_call(CPUS390XState *env, uint32_t 
sccb, uint64_t code)
 printf(sclp(0x%x, 0x% PRIx64 )\n, sccb, code);
 #endif
 
+/* basic checks */
+if (!memory_region_is_ram(phys_page_find(sccb  TARGET_PAGE_BITS)-mr)) {
+return -PGM_ADDRESSING;
+}
 if (sccb  ~0x7ff8ul) {
-fprintf(stderr, KVM: invalid sccb address 0x%x\n, sccb);
-r = -1;
-goto out;
+return -PGM_SPECIFICATION;
 }
 
 switch(code) {
@@ -2405,22 +2412,24 @@ int sclp_service_call(CPUS390XState *env, uint32_t 
sccb, uint64_t code)
 #ifdef DEBUG_HELPER
 printf(KVM: invalid sclp call 0x%x / 0x% PRIx64 x\n, sccb, 
code);
 #endif
-r = -1;
+r = 3;
 break;
 }
 
-out:
 return r;
 }
 
 /* SCLP service call */
 uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
 {
-if (sclp_service_call(env, r1, r2)) {
-return 3;
-}
+int r;
 
-return 0;
+r = sclp_service_call(env, r1, r2);
+if (r  0) {
+program_interrupt(env, -r, 4);
+return 0;
+}
+return r;
 }
 
 /* DIAG */
-- 
1.7.0.1




[Qemu-devel] [PATCH 6/7] s390: sclp ascii console support

2012-07-24 Thread Christian Borntraeger
From: Heinz Graalfs graa...@linux.vnet.ibm.com

This code adds console support  by implementing SCLP's ASCII Console
Data event. This is the same console as LPARs ASCII console or z/VMs
sysascii.

The console can be specified manually with something like
-chardev stdio,id=charconsole0 -device 
sclpconsole,chardev=charconsole0,id=console0

Newer kernels will autodetect that console and prefer that over virtio
console.

When data is received from the character layer it creates a service
interrupt to trigger a Read Event Data command from the guest that will
pick up the received character byte-stream.
When characters are echo'ed by the linux guest a Write Event Data occurs
which is forwarded by the Event Facility to the console that supports
a corresponding mask value.
Console resizing is not supported.
The character layer byte-stream is buffered using a fixed size iov
buffer.

Signed-off-by: Heinz Graalfs graa...@linux.vnet.ibm.com
Signed-off-by: Christian Borntraeger borntrae...@de.ibm.com
---
 hw/s390x/Makefile.objs |2 +-
 hw/s390x/sclpconsole.c |  323 
 2 files changed, 324 insertions(+), 1 deletions(-)
 create mode 100644 hw/s390x/sclpconsole.c

diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index ed4e61a..096dfcd 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -3,4 +3,4 @@ obj-y = s390-virtio-bus.o s390-virtio.o
 obj-y := $(addprefix ../,$(obj-y))
 obj-y += sclp.o
 obj-y += event-facility.o
-obj-y += sclpquiesce.o
+obj-y += sclpquiesce.o sclpconsole.o
diff --git a/hw/s390x/sclpconsole.c b/hw/s390x/sclpconsole.c
new file mode 100644
index 000..9a57032
--- /dev/null
+++ b/hw/s390x/sclpconsole.c
@@ -0,0 +1,323 @@
+/*
+ * SCLP event type
+ *Ascii Console Data (VT220 Console)
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Heinz Graalfs graa...@de.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
+ * option) any later version.  See the COPYING file in the top-level directory.
+ *
+ */
+
+#include hw/qdev.h
+#include qemu-thread.h
+
+#include sclp.h
+#include event-facility.h
+
+typedef struct ASCIIConsoleData {
+EventBufferHeader ebh;
+char data[0];
+} QEMU_PACKED ASCIIConsoleData;
+
+qemu_irq sclp_read_vt220;
+
+/* max size for ASCII data in 4K SCCB page */
+#define SIZE_BUFFER_VT220 4080
+
+typedef struct SCLPConsole {
+SCLPEvent event;
+CharDriverState *chr;
+/* io vector   */
+uint8_t *iov;   /* iov buffer pointer  */
+uint8_t *iov_sclp;  /* pointer to SCLP read offset */
+uint8_t *iov_bs;/* pointer byte stream read offset */
+uint32_t iov_data_len;  /* length of byte stream in buffer */
+uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP */
+} SCLPConsole;
+
+/* character layer call-back functions */
+
+/* Return number of bytes that fit into iov buffer */
+static int chr_can_read(void *opaque)
+{
+int can_read;
+SCLPConsole *scon = opaque;
+
+qemu_mutex_lock(scon-event.lock);
+can_read = SIZE_BUFFER_VT220 - scon-iov_data_len;
+qemu_mutex_unlock(scon-event.lock);
+
+return can_read;
+}
+
+/* Receive n bytes from character layer, save in iov buffer,
+ * and set event pending */
+static void receive_from_chr_layer(void *opaque, const uint8_t *buf, int size)
+{
+SCLPConsole *scon = opaque;
+
+assert(scon-iov);
+
+qemu_mutex_lock(scon-event.lock);
+
+/* if new data do not fit into current buffer */
+if (scon-iov_data_len + size  SIZE_BUFFER_VT220) {
+/* character layer sent more than allowed */
+qemu_mutex_unlock(scon-event.lock);
+return;
+}
+/* put byte-stream from character layer into buffer */
+memcpy(scon-iov_bs, buf, size);
+scon-iov_data_len += size;
+scon-iov_sclp_rest += size;
+scon-iov_bs += size;
+scon-event.event_pending = true;
+
+qemu_mutex_unlock(scon-event.lock);
+}
+
+/* Send data from a char device over to the guest */
+static void chr_read(void *opaque, const uint8_t *buf, int size)
+{
+assert(opaque);
+
+receive_from_chr_layer(opaque, buf, size);
+/* trigger SCLP read operation */
+qemu_irq_raise(sclp_read_vt220);
+}
+
+static void chr_event(void *opaque, int event)
+{
+SCLPConsole *scon = opaque;
+
+switch (event) {
+case CHR_EVENT_OPENED:
+if (!scon-iov) {
+scon-iov = g_malloc0(SIZE_BUFFER_VT220);
+scon-iov_sclp = scon-iov;
+scon-iov_bs = scon-iov;
+scon-iov_data_len = 0;
+scon-iov_sclp_rest = 0;
+}
+break;
+case CHR_EVENT_CLOSED:
+if (scon-iov) {
+g_free(scon-iov);
+scon-iov = NULL;
+}
+break;
+}
+}
+
+/* functions to be called by event facility */
+
+static int event_type(void)
+{
+return 

[Qemu-devel] [PULL 0/2] NBD changes for 2012-07-24

2012-07-24 Thread Paolo Bonzini
A small change, introducing the --cache and --aio options I needed while
playing with block device mirroring.

The following changes since commit a21143486b9c6d7a50b7b62877c02b3c686943cb:

  Merge remote-tracking branch 'stefanha/net' into staging (2012-07-23 13:15:34 
-0500)

are available in the git repository at:


  git://github.com/bonzini/qemu.git nbd-next

for you to fetch changes up to 39a5235cd7f367cce7be7b3f4d258452452e38e3:

  qemu-nbd: add --cache and --aio options (2012-07-24 09:31:53 +0200)


Paolo Bonzini (2):
  qemu-nbd: reorganize help message
  qemu-nbd: add --cache and --aio options

 qemu-nbd.c |   75 +---
 1 file changed, 62 insertions(+), 13 deletions(-)
-- 
1.7.10.4




  1   2   3   >