Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 02 Dec 2013 15:51:22 +0100
From:      krichy@cflinux.hu
To:        freebsd-scsi@freebsd.org
Subject:   geom write-cache awareness
Message-ID:  <2cc1e6c1bedf517edd8e3ad0a8c94a7b@cflinux.hu>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
Dear scsi devs,

I am facing with a strange problem, mentioned earlier: I bought an SSD 
for the purpose of zfs ZIL. I made tests regarding its speed under 
linux, after which I decided it will suit my needs. It performs enough 
IOPS for me, and has power-loss protection, so my data is in safe.

Upon attaching the drive, under linux and under freebsd it has its 
write-cache disabled. Linux handles this, and in this way, it does not 
issue FLUSH commands to the device, as it assumes it has its write cache 
disabled. Unfortunately, the drive serves flush commands slow, I dont 
know why. And as FreeBSD currently ignores such settings, and always 
issues the FLUSH command, this makes my drive perform slow on FreeBSD. 
And when I enable the write cache in linux, it gets sending the flush 
commands, it gets also that slow performance.

What would if FreeBSD's geom layer has some knowledge about the 
underlying device's cache setting, and if it knows as it has no or has a 
write-through cache, skip flush commands? Maybe this could improve 
performance in other scenarios also, when one explicitly disables the 
cache. And of course, it would solve my problem also.

As I am not a FreeBSD kernel developer, I just tried to implement such 
awareness for geom and for ata devices only, the diff is attached, it is 
against 9.2-RELENG.

Please review the idea, or give advice how to solve my problem.

Thanks in advance,


Kojedzinszky Richard
[-- Attachment #2 --]
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index cc28311..10e4f9b 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -1242,7 +1242,7 @@ adaregister(struct cam_periph *periph, void *arg)
 		maxio = min(maxio, 256 * softc->params.secsize);
 	softc->disk->d_maxsize = maxio;
 	softc->disk->d_unit = periph->unit_number;
-	softc->disk->d_flags = 0;
+	softc->disk->d_flags = DISKFLAG_WRITE_THROUGH;
 	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE)
 		softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
 	if (softc->flags & ADA_FLAG_CAN_TRIM) {
@@ -1835,6 +1835,12 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
 			}
 		}
 
+		if (ataio->cmd.features == ATA_SF_ENAB_WCACHE) {
+			softc->disk->d_flags &= ~DISKFLAG_WRITE_THROUGH;
+		} else {
+			softc->disk->d_flags |= DISKFLAG_WRITE_THROUGH;
+		}
+
 		softc->state = ADA_STATE_NORMAL;
 		/*
 		 * Since our peripheral may be invalidated by an error
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 16f6c44..2cb4cef 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -404,6 +404,10 @@ g_disk_start(struct bio *bp)
 	case BIO_FLUSH:
 		g_trace(G_T_BIO, "g_disk_flushcache(%s)",
 		    bp->bio_to->name);
+		if (dp->d_flags & DISKFLAG_WRITE_THROUGH) {
+			error = 0;
+			break;
+		}
 		if (!(dp->d_flags & DISKFLAG_CANFLUSHCACHE)) {
 			error = EOPNOTSUPP;
 			break;
diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h
index 5e081c8..a53aa38 100644
--- a/sys/geom/geom_disk.h
+++ b/sys/geom/geom_disk.h
@@ -111,6 +111,7 @@ struct disk {
 #define DISKFLAG_LACKS_GONE	0x10
 #define DISKFLAG_UNMAPPED_BIO	0x20
 #define DISKFLAG_LACKS_DELMAX	0x40
+#define DISKFLAG_WRITE_THROUGH	0x80
 
 struct disk *disk_alloc(void);
 void disk_create(struct disk *disk, int version);

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2cc1e6c1bedf517edd8e3ad0a8c94a7b>