kernel - disklabel64 - Increase partition start alignment to 1 megabyte.
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 20 Feb 2010 18:11:28 +0000 (10:11 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sat, 20 Feb 2010 18:11:28 +0000 (10:11 -0800)
* Someone suggested that instead of using a 32K alignment we use a larger
  alignment.  I forgot who suggested it but after thinking about it a bit
  and messing around with swapcache on a SSD I decided it was a good idea.

  SSDs using MLC flash have a physical block size of 128K.  SLC flash has
  a physical block size of 64K.  Most typical cluster operations in
  DragonFly are 64K to 128K but clustered writes are often linear on disk
  leading to larger linear writes from the point of view of the physical
  drive's write cache.

  swapcache and swap operation tends to have even larger write linearities
  and write amplification effects on SSDs can be reduced to better than 1:2
  (verses the 1:10 the vendor typically assumes).

* Virgin disklabel64's layed down by the kernel will now align the
  start of the partition space to 1MB (1024 * 1024).  In for a penny,
  in for a pound.

* Adjust the manual page and note the benefits of using a larger alignment,
  particularly when swapcache is used with SSDs.

sbin/disklabel64/disklabel64.8
sys/kern/subr_disklabel64.c

index 9e9ff76..623b95a 100644 (file)
@@ -561,6 +561,30 @@ Your mileage may vary.
 .Dl "gpt add da0"
 .Dl "disklabel64 -B -r -w da0s0 auto"
 .Dl "disklabel64 -e da0s0"
+.Sh ALIGNMENT
+When a virgin disklabel64 is layed down a
+.Dx 2.5
+or later kernel will align the partition start offset relative to the
+physical drive instead of relative to the slice start.
+This overcomes the issue of fdisk creating a badly aligned slice by default.
+The kernel will use a 1MiB (1024 * 1024 byte) alignment.
+The purpose of this alignment is to match swap and cluster operations
+against the physical block size of the underlying device.
+.Pp
+Even though nearly all devices still report a logical sector size of 512,
+newer hard drives are starting to use larger physical sector sizes
+and, in particular, solid state drives (SSDs) use a physical block size
+of 64K (SLC) or 128K (MLC).  We choose a 1 megabyte alignment to cover our
+bases down the road.  64-bit disklabels are not designed to be put on
+ultra-tiny storage devices.
+.Pp
+It is worth noting that aligning cluster operations is particularly
+important for SSDs and doubly so when
+.Xr swapcache 8
+is used with a SSD.
+Swapcache is able to use large bulk writes which greatly reduces the degree
+of write magnification on SSD media and it is possible to get upwards of
+5x more endurance out of the device than the vendor spec sheet indicates.
 .Sh FILES
 .Bl -tag -width ".Pa /boot/boot2_64" -compact
 .It Pa /boot/boot1_64
index 0ad757a..b3f4b8e 100644 (file)
 #include <sys/kern_syscall.h>
 #include <sys/buf2.h>
 
+/*
+ * Alignment against physical start (verses slice start).  We use a megabyte
+ * here.  Why do we use a megabyte?  Because SSDs already use large 128K
+ * blocks internally (for MLC) and who the hell knows in the future.
+ *
+ * This way if the sysop picks sane values for partition sizes everything
+ * will be nicely aligned, particularly swap for e.g. swapcache, and
+ * clustered operations against larger physical sector sizes for newer HDs,
+ * and so forth.
+ */
+#define PALIGN_SIZE    (1024 * 1024)
+#define PALIGN_MASK    (PALIGN_SIZE - 1)
+
 /*
  * Retrieve the partition start and extent, in blocks.  Return 0 on success,
  * EINVAL on error.
@@ -437,7 +450,7 @@ l64_makevirginlabel(disklabel_t lpx, struct diskslices *ssp,
         */
        lp->d_bbase = ressize;
        lp->d_pbase = lp->d_bbase + ((32768 + blkmask) & ~blkmask);
-       lp->d_pbase = (lp->d_pbase + 32767) & ~(uint64_t)32767;
+       lp->d_pbase = (lp->d_pbase + PALIGN_MASK) & ~(uint64_t)PALIGN_MASK;
 
        /* adjust for slice offset so we are physically aligned */
        lp->d_pbase += 32768 - (sp->ds_offset * info->d_media_blksize) % 32768;