Date: Sun, 9 Sep 2018 13:59:53 -0700 From: Mark Millard <marklmi@yahoo.com> To: Kirk McKusick <mckusick@mckusick.com> Cc: bob prohaska <fbsd@www.zefox.net>, FreeBSD Filesystems <freebsd-fs@FreeBSD.org> Subject: Re: CFT: TRIM Consolodation on UFS/FFS filesystems Message-ID: <23C1A967-1E61-4055-B1A9-66E0FA51E2D9@yahoo.com> In-Reply-To: <A3FFE52A-1163-4F1C-ADD2-B842810E4D4C@yahoo.com> References: <201809062330.w86NUphJ027262@chez.mckusick.com> <B9914A0D-69DC-4D3F-9BA4-D180462B2FA5@yahoo.com> <D2E536B0-B278-4E76-A3A4-3444BF840722@yahoo.com> <A3FFE52A-1163-4F1C-ADD2-B842810E4D4C@yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[I looked up the e.MMC 4.41 information: TRIM was optional back then. TRIM and DISCARD are Mandatory in e.MMC 4.51 . Also It looks to me like microsd{hc,xc} cards do not use=20 EXT_CSD_INAND_CMD38_TRIM in FreeBSD, instead using EXT_CSD_INAND_CMD38_ERASE .] On 2018-Sep-8, at 2:32 AM, Mark Millard <marklmi at yahoo.com> wrote: > On 2018-Sep-8, at 1:36 AM, Mark Millard <marklmi at yahoo.com> wrote: >=20 >> Just an FYI. >>=20 >> I figured out a hack that allows the e.MMC on a microsd card >> adapter to be used to boot and operate the Pine64+ 2GB, in >> DDR52 mode at that. (And so shows what was missing in the >> FreeBSD operation even if the code change is not the >> proper form of an official fix.) >>=20 >> But in the process I discovered that FreeBSD is using >> (for e.MMC in this tested context): >>=20 >> mmc0: REQUEST: CMD38 arg 0x1 flags 0x1d >>=20 >> That "0x1" means: TRIM that forces reads of zeros: the true >> Data Removal command for mmc protocol, a form of erase. 0x3 >> would be DISCARD, the "performance command" that does not >> guarantee what would be read afterwards: no erase required. >>=20 >> TRIM is older (added in e/MCC 4.4). DISCARD is newer (added >> in e.MMC 4.5). Each is mandatory when the version has the >> function at all. I looked up the e.MMC 4.41 information: TRIM was optional back then. TRIM and DISCARD are Mandatory in e.MMC 4.51 . Sorry for the error. >> Does FreeBSD have a policy of preferring erasure when >> there is also the option to not require it? >=20 >=20 > I looked up published SD card material and that command > set encodes differently for the argument: >=20 > 0x1 is DISCARD (also not requiring an erase) > 0x2 is FULE when start LBA=3DLBA0 and end LBA=3DMaxLBA. > Otherwise it is ERASE. > (FreeBSD's mmcsd_delete uses 0x0 for ERASE selection.) >=20 > (I ignore handling violations of start LBA <=3D end LBA <=3D Max LBA > or out of order command sequences. FULE: Full User Area Logical > Erase.) >=20 > It looks like FreeBSD uses mmcsd_delete for both SD and e.MMC > and it is coded for SD to be more optimal (DISCARD), not > differentiating e.MMC from SD for argument values to use. >=20 > In e.MMC 4.5+ 0x2 is a "discard enable" bit in the argument, > and never a FULE or other such. >=20 > In e.MMC the 0x0 case for CMD38's argument is for performing > an erase on erase group(s) instead of sector(s). >=20 > (I'm not describing Secure Request or Force Garbage Collect > being 0x1 for e.MMC: apparently unused by mmcsd_delete .) [I'll note that on the e.MMC fsck_ffs -E with around 60 GiBytes of free space, gstat -pd shows it taking a long time doing deletes for the e.MMC that I have.] It looks to me like microsd{hc,xc} cards and SD cards in general do not use EXT_CSD_INAND_CMD38_TRIM. I say that because . . . Earlier I looked at what the CMD38 command encoding covered. But that need not mean that TRIM is always used. So I looked into that as well. Example code uses MMCSD_USE_TRIM is: use_trim =3D sc->flags & MMCSD_USE_TRIM; . . . if ((sc->flags & MMCSD_INAND_CMD38) !=3D 0) { err =3D mmc_switch(mmcbus, dev, sc->rca, = EXT_CSD_CMD_SET_NORMAL, EXT_CSD_INAND_CMD38, use_trim =3D=3D true ? EXT_CSD_INAND_CMD38_TRIM : = EXT_CSD_INAND_CMD38_ERASE, sc->cmd6_time, true); . . . But the sc->flags bit involved is based on the mmcsd_attach's: static int mmcsd_attach(device_t dev) { device_t mmcbus; struct mmcsd_softc *sc; const uint8_t *ext_csd; off_t erase_size, sector_size, size, wp_size; uintmax_t bytes; int err, i; uint32_t quirks; uint8_t rev; bool comp, ro; char unit[2]; =20 sc =3D device_get_softc(dev); sc->dev =3D dev; sc->mmcbus =3D mmcbus =3D device_get_parent(dev); sc->mode =3D mmc_get_card_type(dev); /* * Note that in principle with an SDHCI-like re-tuning = implementation, * the maximum data size can change at runtime due to a device = removal/ * insertion that results in switches to/from a transfer mode = involving * re-tuning, iff there are multiple devices on a given bus. = Until now * mmc(4) lacks support for rescanning already attached buses, = however, * and sdhci(4) to date has no support for shared buses in the = first * place either. */ sc->max_data =3D mmc_get_max_data(dev); sc->high_cap =3D mmc_get_high_cap(dev); sc->rca =3D mmc_get_rca(dev); sc->cmd6_time =3D mmc_get_cmd6_timeout(dev); quirks =3D mmc_get_quirks(dev); /* Only MMC >=3D 4.x devices support EXT_CSD. */ if (mmc_get_spec_vers(dev) >=3D 4) { MMCBUS_ACQUIRE_BUS(mmcbus, dev); err =3D mmc_send_ext_csd(mmcbus, dev, sc->ext_csd); MMCBUS_RELEASE_BUS(mmcbus, dev); if (err !=3D MMC_ERR_NONE) { device_printf(dev, "Error reading EXT_CSD %s\n", mmcsd_errmsg(err)); return (ENXIO); } } ext_csd =3D sc->ext_csd; if ((quirks & MMC_QUIRK_INAND_CMD38) !=3D 0) { if (mmc_get_spec_vers(dev) < 4) { device_printf(dev, "MMC_QUIRK_INAND_CMD38 set but no = EXT_CSD\n"); return (EINVAL); } sc->flags |=3D MMCSD_INAND_CMD38; } /* * EXT_CSD_SEC_FEATURE_SUPPORT_GB_CL_EN denotes support for both * insecure and secure TRIM. */ if ((ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] & EXT_CSD_SEC_FEATURE_SUPPORT_GB_CL_EN) !=3D 0 && (quirks & MMC_QUIRK_BROKEN_TRIM) =3D=3D 0) { if (bootverbose) device_printf(dev, "taking advantage of = TRIM\n"); sc->flags |=3D MMCSD_USE_TRIM; sc->erase_sector =3D 1; } else sc->erase_sector =3D mmc_get_erase_sector(dev); . . . microsd{hc,xc} cards do not have EXT_CSD and so would not appear to ever assign sc->flags |=3D MMCSD_USE_TRIM . [mmc_send_ext_csd establishes a zero'd area when the operation fails. For SD cards CMD8 is only valid for the Idle state, which is not the context here from what I can tell.] So I get that EXT_CSD_INAND_CMD38_TRIM is only used for e.MMC, not (micro)SD{hc,xc} cards. This means my earlier microsdxc card testing was not testing what I thought it was: instead testing EXT_CSD_INAND_CMD38_ERASE use. =3D=3D=3D Mark Millard marklmi at yahoo.com ( dsl-only.net went away in early 2018-Mar)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?23C1A967-1E61-4055-B1A9-66E0FA51E2D9>