Date: Sat, 20 Sep 2014 01:15:46 -0600 From: "Justin T. Gibbs" <gibbs@scsiguy.com> To: Willem Jan Withagen <wjw@digiware.nl> Cc: freebsd-stable@freebsd.org, Steven Hartland <killing@multiplay.co.uk>, Peter Wemm <peter@wemm.org>, Andriy Gapon <avg@freebsd.org>, Aristedes Maniatis <ari@ish.com.au> Subject: Re: getting to 4K disk blocks in ZFS Message-ID: <05BBE286-A6B6-4F82-A06E-57002EFCA4DE@scsiguy.com> In-Reply-To: <9F3CB84B-E0F1-4343-8E37-4E4A9F252C52@scsiguy.com> References: <540FF3C4.6010305@ish.com.au> <A0A549F7A4094F519A3660697AB4983F@multiplay.co.uk> <54114029.3060507@FreeBSD.org> <2128347.Ah5i0RTCvp@overcee.wemm.org> <541230F1.3060402@digiware.nl> <7D0869A9-C114-4C4F-877A-3FB26AD7737D@scsiguy.com> <9F3CB84B-E0F1-4343-8E37-4E4A9F252C52@scsiguy.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sep 20, 2014, at 12:21 AM, Justin T. Gibbs <gibbs@scsiguy.com> wrote:
> On Sep 19, 2014, at 5:07 PM, Justin T. Gibbs <gibbs@scsiguy.com> =
wrote:
>=20
>> On Sep 11, 2014, at 5:32 PM, Willem Jan Withagen <wjw@digiware.nl> =
wrote:
>>=20
>>> On 11-9-2014 19:49, Peter Wemm wrote:
>>>>> Another downside is 1/4th of uberblocks, 32 vs 128.
>>>>> Also, automatic sector size detection works great for me and I've =
never had
>>>>> a need to manually tweak ashift.
>>>>=20
>>>> Unfortunately, I have. Same drive connected two different ways:
>>>>=20
>>>> da12 at mps1 bus 0 scbus1 target 11 lun 0
>>>> da12: <ATA ST4000VN000-1H41 SC43> Fixed Direct Access SCSI-6 device=20=
>>>> da12: 600.000MB/s transfers
>>>> da12: Command Queueing enabled
>>>> da12: 3815447MB (7814037168 512 byte sectors: 255H 63S/T 486401C)
>>>>=20
>>>> ada1 at ahcich1 bus 0 scbus3 target 0 lun 0
>>>> ada1: <ATA ST4000VN000-1H41 SC43> ATA-8 SATA 3.x device
>>>> ada1: 600.000MB/s transfers (SATA 3.x, UDMA6, PIO 8192bytes)
>>>> ada1: Command Queueing enabled
>>>> ada1: 3815447MB (7814037168 512 byte sectors: 16H 63S/T 16383C)
>>>> ada1: quirks=3D0x1<4K>
>>>>=20
>>>> The 4k flag is missing when it's on the sas controller. The Ident =
strings are=20
>>>> changed.
>>>>=20
>>>> This came up elsewhere recently.
>>>=20
>>> I reported the same fact for the new set of WD REDs I installed.
>>> Seems that ada and da have different quirks tables...
>>> So disks on SATA connectors on the motherboard are diagnosed as =
being 4Kb.
>>> The disks on my twa don't get the quirk and are considered 512b
>>>=20
>>> =97WjW
>>=20
>> I=92m surprised that we have to constantly add quirks. Are these =
drives really failing to report their ata params correctly? Is there a =
reason we don=92t currently utilize the ata params data (which is =
already fetched for trim/unmap detection) to also set lbppbe (logical =
block per physical block exponent) and lalba (lowest aligned lba)? We =
may find that many of the existing quirks are unnecessary if we fix the =
probe code.
>>=20
>> =97
>> Justin
>=20
>=20
> Here=92s a start at using the ata_params sector size data. I think it =
needs to go a bit further and detect situations where the SCSI =
controller=92s emulation gets the logical sector size wrong and fail to =
attach - but I=92m out of steam for tonight.
>=20
> Note that this patch is against Spectra Logic=92s =
FreeBSD/stable/10=92ish tree, so may not apply cleanly for you as is. I =
can rebase it against head tomorrow if there is interest and someone =
else doesn=92t beat me to it.
Hmm. Attachments aren=92t allowed? Here=92s the inlined diff. =
Hopefully Apple Mail won=92t mangle it.
=97
Justin
--- //SpectraBSD/stable/sys/cam/ata/ata_all.c 2014-08-01 =
21:08:39.000000000 -0600
+++ /usr/home/justing/perforce/SpectraBSD/sys/cam/ata/ata_all.c =
2014-08-01 21:08:39.000000000 -0600
@@ -335,7 +335,25 @@
printf("<%s %s %s %s>", vendor, product, revision, fw);
}
=20
+/* (L)ogical (B)locks (P)er (P)hysical (B)lock (E)xponent. */
+uint8_t
+ata_lbppbe(struct ata_params *ident_data)
+{
+ if ((ident_data->pss & ATA_PSS_VALID_MASK) !=3D =
ATA_PSS_VALID_VALUE)
+ return (0);
+ return (ident_data->pss & ATA_PSS_LSPPS);
+}
+
+/* (L)owest (A)ligned (L)ogical (B)lock (A)ddress. */
uint32_t
+ata_lalba(struct ata_params *ident_data)
+{
+ if ((ident_data->lsalign & 0xc000) !=3D 0x4000)
+ return (0);
+ return (ident_data->lsalign & 0x3fff);
+}
+
+uint32_t
ata_logical_sector_size(struct ata_params *ident_data)
{
if ((ident_data->pss & ATA_PSS_VALID_MASK) =3D=3D =
ATA_PSS_VALID_VALUE &&
@@ -346,28 +364,17 @@
return (512);
}
=20
-uint64_t
+uint32_t
ata_physical_sector_size(struct ata_params *ident_data)
{
- if ((ident_data->pss & ATA_PSS_VALID_MASK) =3D=3D =
ATA_PSS_VALID_VALUE) {
- if (ident_data->pss & ATA_PSS_MULTLS) {
- return =
((uint64_t)ata_logical_sector_size(ident_data) *
- (1 << (ident_data->pss & ATA_PSS_LSPPS)));
- } else {
- return =
(uint64_t)ata_logical_sector_size(ident_data);
- }
- }
- return (512);
+ return (ata_logical_sector_size(ident_data) << =
ata_lbppbe(ident_data));
}
=20
uint64_t
ata_logical_sector_offset(struct ata_params *ident_data)
{
- if ((ident_data->lsalign & 0xc000) =3D=3D 0x4000) {
- return ((uint64_t)ata_logical_sector_size(ident_data) *
- (ident_data->lsalign & 0x3fff));
- }
- return (0);
+ return ((uint64_t)ata_logical_sector_size(ident_data) *
+ ata_lalba(ident_data));
}
=20
void
--- //SpectraBSD/stable/sys/cam/ata/ata_all.h 2014-08-01 =
21:08:39.000000000 -0600
+++ /usr/home/justing/perforce/SpectraBSD/sys/cam/ata/ata_all.h =
2014-08-01 21:08:39.000000000 -0600
@@ -111,8 +111,10 @@
void ata_print_ident(struct ata_params *ident_data);
void ata_print_ident_short(struct ata_params *ident_data);
=20
+uint8_t ata_lbppbe(struct ata_params *ident_data);
+uint32_t ata_lalba(struct ata_params *ident_data);
uint32_t ata_logical_sector_size(struct ata_params *ident_data);
-uint64_t ata_physical_sector_size(struct ata_params *ident_data);
+uint32_t ata_physical_sector_size(struct ata_params *ident_data);
uint64_t ata_logical_sector_offset(struct ata_params =
*ident_data);
=20
void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t =
features,
--- //SpectraBSD/stable/sys/cam/scsi/scsi_da.c 2014-09-19 =
23:21:40.000000000 -0600
+++ /usr/home/justing/perforce/SpectraBSD/sys/cam/scsi/scsi_da.c =
2014-09-19 23:21:40.000000000 -0600
@@ -2039,6 +2041,24 @@
daschedule(periph);
wakeup(&softc->disk->d_mediasize);
if ((softc->flags & DA_FLAG_ANNOUNCED) =3D=3D 0) {
+
+ /*
+ * Create our sysctl variables, now that we know
+ * we have successfully attached.
+ */
+ /* increase the refcount */
+ if (cam_periph_acquire(periph) =3D=3D CAM_REQ_CMP) {
+ taskqueue_enqueue(taskqueue_thread,
+ &softc->sysctl_task);
+ xpt_announce_periph(periph,
+ softc->announce_buf);
+ xpt_announce_quirks(periph, softc->quirks.flags,
+ DA_Q_BIT_STRING);
+ } else {
+ xpt_print(periph->path, "fatal error, "
+ "could not acquire reference count\n");
+ }
+
softc->flags |=3D DA_FLAG_ANNOUNCED;
cam_periph_unhold(periph);
} else
@@ -3360,26 +3381,6 @@
}
}
free(csio->data_ptr, M_SCSIDA);
- if (softc->announce_buf[0] !=3D '\0' &&
- ((softc->flags & DA_FLAG_ANNOUNCED) =3D=3D 0)) {
- /*
- * Create our sysctl variables, now that we know
- * we have successfully attached.
- */
- /* increase the refcount */
- if (cam_periph_acquire(periph) =3D=3D =
CAM_REQ_CMP) {
- taskqueue_enqueue(taskqueue_thread,
- &softc->sysctl_task);
- xpt_announce_periph(periph,
- =
softc->announce_buf);
- xpt_announce_quirks(periph, =
softc->quirks.flags,
- DA_Q_BIT_STRING);
- } else {
- xpt_print(periph->path, "fatal error, "
- "could not acquire reference =
count\n");
- }
- }
-
/* We already probed the device. */
if (softc->flags & DA_FLAG_PROBED) {
daprobedone(periph, done_ccb);
@@ -3633,10 +3578,13 @@
}
case DA_CCB_PROBE_ATA:
{
- int i;
+ struct scsi_read_capacity_data_long rcaplong;
struct ata_params *ata_params;
+ struct disk_params *dp;
int16_t *ptr;
+ int i;
=20
+ dp =3D &softc->params;
ata_params =3D (struct ata_params *)csio->data_ptr;
ptr =3D (uint16_t *)ata_params;
=20
@@ -3658,6 +3606,27 @@
*/
if (ata_params->media_rotation_rate =3D=3D 1)
softc->sort_io_queue =3D 0;
+
+ /*
+ * Perform our own emulation of read capacity =
data
+ * rather than rely on the SCSI controller to =
get
+ * it right.
+ */
+ memset(&rcaplong, 0, sizeof(rcaplong));
+ rcaplong.prot_lbppbe =3D ata_lbppbe(ata_params);
+ scsi_ulto2b(ata_lalba(ata_params),
+ rcaplong.lalba_lbp);
+ dasetgeom(periph, =
ata_logical_sector_size(ata_params),
+ dp->sectors - 1, &rcaplong, =
sizeof(rcaplong));
+ snprintf(softc->announce_buf,
+ sizeof(softc->announce_buf),
+ "%juMB (%ju %u byte sectors: %dH %dS/T "
+ "%dC)", (uintmax_t)
+ (((uintmax_t)dp->secsize *
+ dp->sectors) / (1024*1024)),
+ (uintmax_t)dp->sectors,
+ dp->secsize, dp->heads,
+ dp->secs_per_track, dp->cylinders);
} else {
int error;
error =3D daerror(done_ccb, CAM_RETRY_SELTO,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?05BBE286-A6B6-4F82-A06E-57002EFCA4DE>
