From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Iz8FE-00089n-9G for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:44 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Iz8FC-00088R-SF for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:43 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Iz8FC-00088M-51 for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:42 -0500 Received: from ecfrec.frec.bull.fr ([129.183.4.8]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Iz8F9-0002NT-Ky for qemu-devel@nongnu.org; Mon, 03 Dec 2007 05:09:41 -0500 Received: from localhost (localhost [127.0.0.1]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id E293D19D912 for ; Mon, 3 Dec 2007 11:09:37 +0100 (CET) Received: from ecfrec.frec.bull.fr ([127.0.0.1]) by localhost (ecfrec.frec.bull.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 18605-05 for ; Mon, 3 Dec 2007 11:09:34 +0100 (CET) Received: from ecn002.frec.bull.fr (ecn002.frec.bull.fr [129.183.4.6]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id 5632919D9D2 for ; Mon, 3 Dec 2007 11:09:31 +0100 (CET) In-Reply-To: <1196676559385@bull.net> Date: Mon, 3 Dec 2007 11:09:20 +0100 Message-Id: <1196676560457@bull.net> Mime-Version: 1.0 From: Laurent Vivier Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" Subject: [Qemu-devel] [PATCH 1/2 v2] Add "cache" parameter to "-drive" Reply-To: Laurent Vivier , qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org This patch adds a new parameter to "-drive" Using "cache=3Doff" with "-drive" will open the disk image file using "O_DIRECT". By default, "cache" is set to "on" to keep original behavior of qemu. example: "-drive file=3Dmy_disk.qcow2,cache=3Doff" --- block-raw.c | 12 ++++++++++++ block.c | 2 +- block.h | 1 + hw/fdc.c | 7 ++++++- hw/ide.c | 18 ++++++++++++++---- hw/scsi-disk.c | 3 ++- hw/sd.c | 11 ++++++++++- osdep.c | 20 ++++++++++++++++++++ osdep.h | 1 + vl.c | 26 +++++++++++++++++++++++--- 10 files changed, 90 insertions(+), 11 deletions(-) Index: qemu/block-raw.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/block-raw.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/block-raw.c 2007-12-03 09:54:47.000000000 +0100 @@ -107,6 +107,10 @@ static int raw_open(BlockDriverState *bs } if (flags & BDRV_O_CREAT) open_flags |=3D O_CREAT | O_TRUNC; +#ifdef O_DIRECT + if (flags & BDRV_O_DIRECT) + open_flags |=3D O_DIRECT; +#endif =20 s->type =3D FTYPE_FILE; =20 @@ -660,6 +664,10 @@ static int hdev_open(BlockDriverState *b open_flags |=3D O_RDONLY; bs->read_only =3D 1; } +#ifdef O_DIRECT + if (flags & BDRV_O_DIRECT) + open_flags |=3D O_DIRECT; +#endif =20 s->type =3D FTYPE_FILE; #if defined(__linux__) @@ -981,6 +989,8 @@ static int raw_open(BlockDriverState *bs #else overlapped =3D FILE_FLAG_OVERLAPPED; #endif + if (flags & BDRV_O_DIRECT) + overlapped |=3D FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; s->hfile =3D CreateFile(filename, access_flags, FILE_SHARE_READ, NULL, create_flags, overlapped, NULL); @@ -1349,6 +1359,8 @@ static int hdev_open(BlockDriverState *b #else overlapped =3D FILE_FLAG_OVERLAPPED; #endif + if (flags & BDRV_O_DIRECT) + overlapped |=3D FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH; s->hfile =3D CreateFile(filename, access_flags, FILE_SHARE_READ, NULL, create_flags, overlapped, NULL); Index: qemu/block.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/block.h 2007-12-03 09:53:31.000000000 +0100 +++ qemu/block.h 2007-12-03 09:54:47.000000000 +0100 @@ -44,6 +44,7 @@ typedef struct QEMUSnapshotInfo { use a disk image format on top of it (default for bdrv_file_open()) */ +#define BDRV_O_DIRECT 0x0020 =20 #ifndef QEMU_IMG void bdrv_info(void); Index: qemu/vl.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/vl.c 2007-12-03 09:53:43.000000000 +0100 +++ qemu/vl.c 2007-12-03 09:54:47.000000000 +0100 @@ -4851,8 +4851,11 @@ static int drive_init(const char *str, i BlockDriverState *bdrv; int max_devs; int index; + int cache; + int bdrv_flags; char *params[] =3D { "bus", "unit", "if", "index", "cyls", "heads", - "secs", "trans", "media", "snapshot", "file", NULL = }; + "secs", "trans", "media", "snapshot", "file", + "cache", NULL }; =20 if (check_params(buf, sizeof(buf), params, str) < 0) { fprintf(stderr, "qemu: unknowm parameter '%s' in '%s'\n", @@ -4866,6 +4869,7 @@ static int drive_init(const char *str, i unit_id =3D -1; translation =3D BIOS_ATA_TRANSLATION_AUTO; index =3D -1; + cache =3D 1; =20 if (!strcmp(machine->name, "realview") || !strcmp(machine->name, "SS-5") || @@ -5005,6 +5009,17 @@ static int drive_init(const char *str, i } } =20 + if (get_param_value(buf, sizeof(buf), "cache", str)) { + if (!strcmp(buf, "off")) + cache =3D 0; + else if (!strcmp(buf, "on")) + cache =3D 1; + else { + fprintf(stderr, "qemu: invalid cache option\n"); + return -1; + } + } + get_param_value(file, sizeof(file), "file", str); =20 /* compute bus and unit according index */ @@ -5092,8 +5107,12 @@ static int drive_init(const char *str, i } if (!file[0]) return 0; - if (bdrv_open(bdrv, file, snapshot ? BDRV_O_SNAPSHOT : 0) < 0 || - qemu_key_check(bdrv, file)) { + bdrv_flags =3D 0; + if (snapshot) + bdrv_flags |=3D BDRV_O_SNAPSHOT; + if (!cache) + bdrv_flags |=3D BDRV_O_DIRECT; + if (bdrv_open(bdrv, file, bdrv_flags) < 0 || qemu_key_check(bdrv, file= )) { fprintf(stderr, "qemu: could not open disk image %s\n", file); return -1; @@ -7440,6 +7459,7 @@ static void help(int exitcode) "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 m= aster)\n" "-drive [file=3Dfile][,if=3Dtype][,bus=3Dn][,unit=3Dm][,media=3Dd][ind= ex=3Di]\n" " [,cyls=3Dc,heads=3Dh,secs=3Ds[,trans=3Dt]][snapshot=3Do= n|off]\n" + " [cache=3Don|off]\n" " use 'file' as a drive image\n" "-mtdblock file use 'file' as on-board Flash memory image\n" "-sd file use 'file' as SecureDigital card image\n" Index: qemu/hw/ide.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/hw/ide.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/hw/ide.c 2007-12-03 09:54:47.000000000 +0100 @@ -365,7 +365,7 @@ typedef struct IDEState { EndTransferFunc *end_transfer_func; uint8_t *data_ptr; uint8_t *data_end; - uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; + uint8_t *io_buffer; QEMUTimer *sector_write_timer; /* only used for win2k install hack */ uint32_t irq_count; /* counts IRQs when using win2k install hack */ /* CF-ATA extended error */ @@ -2372,17 +2372,24 @@ struct partition { static int guess_disk_lchs(IDEState *s, int *pcylinders, int *pheads, int *psectors) { - uint8_t buf[512]; + uint8_t *buf; int ret, i, heads, sectors, cylinders; struct partition *p; uint32_t nr_sects; =20 + buf =3D qemu_memalign(512, 512); + if (buf =3D=3D NULL) + return -1; ret =3D bdrv_read(s->bs, 0, buf, 1); - if (ret < 0) + if (ret < 0) { + qemu_free(buf); return -1; + } /* test msdos magic */ - if (buf[510] !=3D 0x55 || buf[511] !=3D 0xaa) + if (buf[510] !=3D 0x55 || buf[511] !=3D 0xaa) { + qemu_free(buf); return -1; + } for(i =3D 0; i < 4; i++) { p =3D ((struct partition *)(buf + 0x1be)) + i; nr_sects =3D le32_to_cpu(p->nr_sects); @@ -2403,9 +2410,11 @@ static int guess_disk_lchs(IDEState *s, printf("guessed geometry: LCHS=3D%d %d %d\n", cylinders, heads, sectors); #endif + qemu_free(buf); return 0; } } + qemu_free(buf); return -1; } =20 @@ -2420,6 +2429,7 @@ static void ide_init2(IDEState *ide_stat =20 for(i =3D 0; i < 2; i++) { s =3D ide_state + i; + s->io_buffer =3D qemu_memalign(512, MAX_MULT_SECTORS*512 + 4); if (i =3D=3D 0) s->bs =3D hd0; else Index: qemu/block.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/block.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/block.c 2007-12-03 09:54:47.000000000 +0100 @@ -380,7 +380,7 @@ int bdrv_open2(BlockDriverState *bs, con /* Note: for compatibility, we open disk image files as RDWR, and RDONLY as fallback */ if (!(flags & BDRV_O_FILE)) - open_flags =3D BDRV_O_RDWR; + open_flags =3D BDRV_O_RDWR | (flags & BDRV_O_DIRECT); else open_flags =3D flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); ret =3D drv->bdrv_open(bs, filename, open_flags); Index: qemu/hw/scsi-disk.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/hw/scsi-disk.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/hw/scsi-disk.c 2007-12-03 09:54:47.000000000 +0100 @@ -46,7 +46,7 @@ typedef struct SCSIRequest { int sector_count; /* The amounnt of data in the buffer. */ int buf_len; - uint8_t dma_buf[SCSI_DMA_BUF_SIZE]; + uint8_t *dma_buf; BlockDriverAIOCB *aiocb; struct SCSIRequest *next; } SCSIRequest; @@ -78,6 +78,7 @@ static SCSIRequest *scsi_new_request(SCS free_requests =3D r->next; } else { r =3D qemu_malloc(sizeof(SCSIRequest)); + r->dma_buf =3D qemu_memalign(512, SCSI_DMA_BUF_SIZE); } r->dev =3D s; r->tag =3D tag; Index: qemu/hw/sd.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/hw/sd.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/hw/sd.c 2007-12-03 09:54:47.000000000 +0100 @@ -1284,10 +1284,17 @@ int sd_do_command(SDState *sd, struct sd static void sd_blk_read(BlockDriverState *bdrv, void *data, uint32_t addr, uint32_t len) { - uint8_t buf[512]; + uint8_t *buf; uint32_t end =3D addr + len; =20 + buf =3D qemu_memalign(512, 512); + if (buf =3D=3D NULL) { + printf("sd_blk_read: cannot allocate memory\n"); + return; + } + if (!bdrv || bdrv_read(bdrv, addr >> 9, buf, 1) =3D=3D -1) { + qemu_free(buf); printf("sd_blk_read: read error on host side\n"); return; } @@ -1297,11 +1304,13 @@ static void sd_blk_read(BlockDriverState =20 if (bdrv_read(bdrv, end >> 9, buf, 1) =3D=3D -1) { printf("sd_blk_read: read error on host side\n"); + qemu_free(buf); return; } memcpy(data + 512 - (addr & 511), buf, end & 511); } else memcpy(data, buf + (addr & 511), len); + qemu_free(buf); } =20 static void sd_blk_write(BlockDriverState *bdrv, Index: qemu/hw/fdc.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/hw/fdc.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/hw/fdc.c 2007-12-03 09:54:47.000000000 +0100 @@ -382,7 +382,7 @@ struct fdctrl_t { uint8_t cur_drv; uint8_t bootsel; /* Command FIFO */ - uint8_t fifo[FD_SECTOR_LEN]; + uint8_t *fifo; uint32_t data_pos; uint32_t data_len; uint8_t data_state; @@ -598,6 +598,11 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int fdctrl =3D qemu_mallocz(sizeof(fdctrl_t)); if (!fdctrl) return NULL; + fdctrl->fifo =3D qemu_memalign(512, FD_SECTOR_LEN); + if (fdctrl->fifo =3D=3D NULL) { + qemu_free(fdctrl); + return NULL; + } fdctrl->result_timer =3D qemu_new_timer(vm_clock, fdctrl_result_timer, fdctrl); =20 Index: qemu/osdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/osdep.c 2007-12-03 09:53:31.000000000 +0100 +++ qemu/osdep.c 2007-12-03 09:54:47.000000000 +0100 @@ -60,6 +60,10 @@ void *qemu_malloc(size_t size) } =20 #if defined(_WIN32) +void *qemu_memalign(size_t alignment, size_t size) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); +} =20 void *qemu_vmalloc(size_t size) { @@ -171,6 +175,22 @@ static void kqemu_vfree(void *ptr) =20 #endif =20 +void *qemu_memalign(size_t alignment, size_t size) +{ +#if defined(_POSIX_C_SOURCE) + int ret; + void *ptr; + ret =3D posix_memalign(&ptr, alignment, size); + if (ret !=3D 0) + return NULL; + return ptr; +#elif defined(_BSD) + return valloc(size); +#else + return memalign(alignment, size); +#endif +} + /* alloc shared memory pages */ void *qemu_vmalloc(size_t size) { Index: qemu/osdep.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu.orig/osdep.h 2007-12-03 09:53:31.000000000 +0100 +++ qemu/osdep.h 2007-12-03 09:54:47.000000000 +0100 @@ -48,6 +48,7 @@ void *qemu_mallocz(size_t size); void qemu_free(void *ptr); char *qemu_strdup(const char *str); =20 +void *qemu_memalign(size_t alignment, size_t size); void *qemu_vmalloc(size_t size); void qemu_vfree(void *ptr); =20