[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v8 07/54] Add qemu_get_buffer_in_place to avoid copi
From: |
Dr. David Alan Gilbert (git) |
Subject: |
[Qemu-devel] [PATCH v8 07/54] Add qemu_get_buffer_in_place to avoid copies some of the time |
Date: |
Tue, 29 Sep 2015 09:37:31 +0100 |
From: "Dr. David Alan Gilbert" <address@hidden>
qemu_get_buffer always copies the data it reads to a users buffer,
however in many cases the file buffer inside qemu_file could be given
back to the caller, avoiding the copy. This isn't always possible
depending on the size and alignment of the data.
Thus 'qemu_get_buffer_in_place' either copies the data to a supplied
buffer or updates a pointer to the internal buffer if convenient.
Signed-off-by: Dr. David Alan Gilbert <address@hidden>
Reviewed-by: Amit Shah <address@hidden>
---
include/migration/qemu-file.h | 2 ++
migration/qemu-file.c | 47 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index ea49f33..ca96461 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -166,6 +166,8 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
int level);
int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src);
+int qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, int size);
+
/*
* Note that you can only peek continuous bytes from where the current pointer
* is; you aren't guaranteed to be able to peak to +n bytes unless you've
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 6bb3dc1..05a41b3 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -434,6 +434,53 @@ int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
}
/*
+ * Read 'size' bytes of data from the file.
+ * 'size' can be larger than the internal buffer.
+ *
+ * The data:
+ * may be held on an internal buffer (in which case *buf is updated
+ * to point to it) that is valid until the next qemu_file operation.
+ * OR
+ * will be copied to the *buf that was passed in.
+ *
+ * The code tries to avoid the copy if possible.
+ *
+ * It will return size bytes unless there was an error, in which case it will
+ * return as many as it managed to read (assuming blocking fd's which
+ * all current QEMUFile are)
+ *
+ * Note: Since **buf may get changed, the caller should take care to
+ * keep a pointer to the original buffer if it needs to deallocate it.
+ */
+int qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, int size)
+{
+ int pending = size;
+ int done = 0;
+ bool first = true;
+
+ while (pending > 0) {
+ int res;
+ uint8_t *src;
+
+ res = qemu_peek_buffer(f, &src, MIN(pending, IO_BUF_SIZE), 0);
+ if (res == 0) {
+ return done;
+ }
+ qemu_file_skip(f, res);
+ done += res;
+ pending -= res;
+ if (first && res == size) {
+ *buf = src;
+ break;
+ }
+ first = false;
+ memcpy(buf, src, res);
+ buf += res;
+ }
+ return done;
+}
+
+/*
* Peeks a single byte from the buffer; this isn't guaranteed to work if
* offset leaves a gap after the previous read/peeked data.
*/
--
2.5.0
- [Qemu-devel] [PATCH v8 00/54] Postcopy implementation, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 02/54] Provide runtime Target page information, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 01/54] Add postcopy documentation, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 04/54] Move configuration section writing, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 03/54] Init page sizes in qtest, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 06/54] Rename mis->file to from_src_file, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 05/54] qemu_ram_block_from_host, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 07/54] Add qemu_get_buffer_in_place to avoid copies some of the time,
Dr. David Alan Gilbert (git) <=
- [Qemu-devel] [PATCH v8 08/54] Add wrapper for setting blocking status on a QEMUFile, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 09/54] Add QEMU_MADV_NOHUGEPAGE, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 10/54] migration/ram.c: Use RAMBlock rather than MemoryRegion, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 11/54] ram_debug_dump_bitmap: Dump a migration bitmap as text, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 12/54] migrate_init: Call from savevm, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 13/54] Move dirty page search state into separate structure, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 14/54] ram_find_and_save_block: Split out the finding, Dr. David Alan Gilbert (git), 2015/10/01
- [Qemu-devel] [PATCH v8 15/54] Rename save_live_complete to save_live_complete_precopy, Dr. David Alan Gilbert (git), 2015/10/01