From owner-svn-src-projects@FreeBSD.ORG Fri Mar 6 00:23:39 2015 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 79BD61A4; Fri, 6 Mar 2015 00:23:39 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 59BB4F33; Fri, 6 Mar 2015 00:23:39 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t260Ndcm077068; Fri, 6 Mar 2015 00:23:39 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t260NdxS077067; Fri, 6 Mar 2015 00:23:39 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201503060023.t260NdxS077067@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Fri, 6 Mar 2015 00:23:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r279679 - projects/iosched/sys/cam/ata X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Mar 2015 00:23:39 -0000 Author: imp Date: Fri Mar 6 00:23:38 2015 New Revision: 279679 URL: https://svnweb.freebsd.org/changeset/base/279679 Log: Create sysctl to publish and change the delete method used, similar to the da drive. Modified: projects/iosched/sys/cam/ata/ata_da.c Modified: projects/iosched/sys/cam/ata/ata_da.c ============================================================================== --- projects/iosched/sys/cam/ata/ata_da.c Fri Mar 6 00:23:23 2015 (r279678) +++ projects/iosched/sys/cam/ata/ata_da.c Fri Mar 6 00:23:38 2015 (r279679) @@ -113,6 +113,23 @@ typedef enum { #define ccb_state ppriv_field0 #define ccb_bp ppriv_ptr1 +typedef enum { + ADA_DELETE_NONE, + ADA_DELETE_DISABLE, + ADA_DELETE_CFA_ERASE, + ADA_DELETE_DSM_TRIM, + ADA_DELETE_NCQ_DSM_TRIM, + ADA_DELETE_MIN = ADA_DELETE_CFA_ERASE, + ADA_DELETE_MAX = ADA_DELETE_NCQ_DSM_TRIM, +} ada_delete_methods; + +static const char *ada_delete_method_names[] = + { "NONE", "DISABLE", "CFA_ERASE", "DSM_TRIM", "NCQ_DSM_TRIM" }; +#if 0 +static const char *ada_delete_method_desc[] = + { "NONE", "DISABLED", "CFA Erase", "DSM Trim", "DSM Trim via NCQ" }; +#endif + struct disk_params { u_int8_t heads; u_int8_t secs_per_track; @@ -137,6 +154,7 @@ struct ada_softc { ada_flags flags; ada_quirks quirks; int sort_io_queue; + ada_delete_methods delete_method; int trim_max_ranges; int trim_running; int read_ahead; @@ -618,6 +636,8 @@ static struct periph_driver adadriver = TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0 }; +static int adadeletemethodsysctl(SYSCTL_HANDLER_ARGS); + PERIPHDRIVER_DECLARE(ada, adadriver); static MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers"); @@ -954,6 +974,20 @@ adacleanup(struct cam_periph *periph) } static void +adasetdeletemethod(struct ada_softc *softc) +{ + + if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) + softc->delete_method = ADA_DELETE_NCQ_DSM_TRIM; + else if (softc->flags & ADA_FLAG_CAN_TRIM) + softc->delete_method = ADA_DELETE_DSM_TRIM; + else if ((softc->flags & ADA_FLAG_CAN_CFA) && !(softc->flags & ADA_FLAG_CAN_48BIT)) + softc->delete_method = ADA_DELETE_CFA_ERASE; + else + softc->delete_method = ADA_DELETE_NONE; +} + +static void adaasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) { @@ -1036,6 +1070,7 @@ adaasync(void *callback_arg, u_int32_t c } else softc->flags &= ~(ADA_FLAG_CAN_TRIM | ADA_FLAG_CAN_NCQ_TRIM); + adasetdeletemethod(softc); cam_periph_async(periph, code, path, arg); break; } @@ -1112,6 +1147,10 @@ adasysctlinit(void *context, int pending return; } + SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), + OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW, + softc, 0, adadeletemethodsysctl, "A", + "BIO_DELETE execution method"); SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "read_ahead", CTLFLAG_RW | CTLFLAG_MPSAFE, &softc->read_ahead, 0, "Enable disk read ahead."); @@ -1160,6 +1199,43 @@ adagetattr(struct bio *bp) return ret; } +static int +adadeletemethodsysctl(SYSCTL_HANDLER_ARGS) +{ + char buf[16]; + const char *p; + struct ada_softc *softc; + int i, error, value, methods; + + softc = (struct ada_softc *)arg1; + + value = softc->delete_method; + if (value < 0 || value > ADA_DELETE_MAX) + p = "UNKNOWN"; + else + p = ada_delete_method_names[value]; + strncpy(buf, p, sizeof(buf)); + error = sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error != 0 || req->newptr == NULL) + return (error); + methods = 1 << ADA_DELETE_DISABLE; + if ((softc->flags & ADA_FLAG_CAN_CFA) && + !(softc->flags & ADA_FLAG_CAN_48BIT)) + methods |= 1 << ADA_DELETE_CFA_ERASE; + if (softc->flags & ADA_FLAG_CAN_TRIM) + methods |= 1 << ADA_DELETE_DSM_TRIM; + if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) + methods |= 1 << ADA_DELETE_NCQ_DSM_TRIM; + for (i = 0; i <= ADA_DELETE_MAX; i++) { + if (!(methods & (1 << i)) || + strcmp(buf, ada_delete_method_names[i]) != 0) + continue; + softc->delete_method = i; + return (0); + } + return (EINVAL); +} + static cam_status adaregister(struct cam_periph *periph, void *arg) { @@ -1218,6 +1294,8 @@ adaregister(struct cam_periph *periph, v if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA) softc->flags |= ADA_FLAG_CAN_CFA; + adasetdeletemethod(softc); + periph->softc = softc; /* @@ -1343,6 +1421,7 @@ adaregister(struct cam_periph *periph, v softc->disk->d_fwsectors = softc->params.secs_per_track; softc->disk->d_fwheads = softc->params.heads; ata_disk_firmware_geom_adjust(softc->disk); + adasetdeletemethod(softc); if (ada_legacy_aliases) { #ifdef ATA_STATIC_ID @@ -1581,14 +1660,17 @@ adastart(struct cam_periph *periph, unio /* Run TRIM if not running yet. */ if (!softc->trim_running && (bp = bioq_first(&softc->trim_queue)) != 0) { - if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) { + switch (softc->delete_method) { + case ADA_DELETE_NCQ_DSM_TRIM: ada_ncq_dsmtrim(softc, bp, ataio); - } else if (softc->flags & ADA_FLAG_CAN_TRIM) { + break; + case ADA_DELETE_DSM_TRIM: ada_dsmtrim(softc, bp, ataio); - } else if ((softc->flags & ADA_FLAG_CAN_CFA) && - !(softc->flags & ADA_FLAG_CAN_48BIT)) { + break; + case ADA_DELETE_CFA_ERASE: ada_cfaerase(softc, bp, ataio); - } else { + break; + default: panic("adastart: BIO_DELETE without method, not possible."); } softc->trim_running = 1; @@ -1835,6 +1917,7 @@ adadone(struct cam_periph *periph, union (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) != 0) { softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM; error = 0; + adasetdeletemethod(softc); } } else { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)