From owner-svn-src-stable-12@freebsd.org Tue Dec 3 16:48:22 2019 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id ED71C1B522C; Tue, 3 Dec 2019 16:48:22 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47S7GG5YB9z4bxg; Tue, 3 Dec 2019 16:48:22 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A1A5C1A9EC; Tue, 3 Dec 2019 16:48:22 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xB3GmMeo090239; Tue, 3 Dec 2019 16:48:22 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xB3GmM3j090234; Tue, 3 Dec 2019 16:48:22 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201912031648.xB3GmM3j090234@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 3 Dec 2019 16:48:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r355337 - in stable/12/sys/cam: . scsi X-SVN-Group: stable-12 X-SVN-Commit-Author: mav X-SVN-Commit-Paths: in stable/12/sys/cam: . scsi X-SVN-Commit-Revision: 355337 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Dec 2019 16:48:23 -0000 Author: mav Date: Tue Dec 3 16:48:21 2019 New Revision: 355337 URL: https://svnweb.freebsd.org/changeset/base/355337 Log: MFC r355010: Make CAM use root_mount_hold_token() to delay boot. Before this change CAM used config_intrhook_establish() for this purpose, but that approach does not allow to delay it again after releasing once. USB stack uses root_mount_hold() to delay boot until bus scan is complete. But once it is, CAM had no time to scan SCSI bus, registered by umass(4), if it already done other scans and called config_intrhook_disestablish(). The new approach makes it work smooth, assuming the USB device is found during the initial bus scan. Devices appearing on USB bus later may still require setting kern.cam.boot_delay, but hopefully those are minority. Modified: stable/12/sys/cam/cam_xpt.c stable/12/sys/cam/scsi/scsi_enc.c stable/12/sys/cam/scsi/scsi_enc_internal.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/cam/cam_xpt.c ============================================================================== --- stable/12/sys/cam/cam_xpt.c Tue Dec 3 16:47:04 2019 (r355336) +++ stable/12/sys/cam/cam_xpt.c Tue Dec 3 16:48:21 2019 (r355337) @@ -99,13 +99,6 @@ MALLOC_DEFINE(M_CAMDEV, "CAM DEV", "CAM devices"); MALLOC_DEFINE(M_CAMCCB, "CAM CCB", "CAM CCBs"); MALLOC_DEFINE(M_CAMPATH, "CAM path", "CAM paths"); -/* Object for defering XPT actions to a taskqueue */ -struct xpt_task { - struct task task; - void *data1; - uintptr_t data2; -}; - struct xpt_softc { uint32_t xpt_generation; @@ -129,10 +122,10 @@ struct xpt_softc { TAILQ_HEAD(,cam_eb) xpt_busses; u_int bus_generation; - struct intr_config_hook xpt_config_hook; - int boot_delay; struct callout boot_callout; + struct task boot_task; + struct root_hold_token xpt_rootmount; struct mtx xpt_topo_lock; struct mtx xpt_lock; @@ -273,6 +266,7 @@ static struct cam_et* static struct cam_ed* xpt_find_device(struct cam_et *target, lun_id_t lun_id); static void xpt_config(void *arg); +static void xpt_hold_boot_locked(void); static int xpt_schedule_dev(struct camq *queue, cam_pinfo *dev_pinfo, u_int32_t new_priority); static xpt_devicefunc_t xptpassannouncefunc; @@ -881,7 +875,7 @@ xpt_rescan(union ccb *ccb) } } TAILQ_INSERT_TAIL(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe); - xsoftc.buses_to_config++; + xpt_hold_boot_locked(); wakeup(&xsoftc.ccb_scanq); xpt_unlock_buses(); } @@ -913,6 +907,7 @@ xpt_init(void *dummy) */ xsoftc.boot_delay = CAM_BOOT_DELAY; #endif + /* * The xpt layer is, itself, the equivalent of a SIM. * Allow 16 ccbs in the ccb pool for it. This should @@ -979,14 +974,11 @@ xpt_init(void *dummy) "- failing attach\n"); return (ENOMEM); } + /* * Register a callback for when interrupts are enabled. */ - xsoftc.xpt_config_hook.ich_func = xpt_config; - if (config_intrhook_establish(&xsoftc.xpt_config_hook) != 0) { - printf("xpt_init: config_intrhook_establish failed " - "- failing attach\n"); - } + config_intrhook_oneshot(xpt_config, NULL); return (0); } @@ -5148,6 +5140,10 @@ xpt_stop_tags(struct cam_path *path) xpt_action((union ccb *)&crs); } +/* + * Assume all possible buses are detected by this time, so allow boot + * as soon as they all are scanned. + */ static void xpt_boot_delay(void *arg) { @@ -5155,12 +5151,26 @@ xpt_boot_delay(void *arg) xpt_release_boot(); } +/* + * Now that all config hooks have completed, start boot_delay timer, + * waiting for possibly still undetected buses (USB) to appear. + */ static void +xpt_ch_done(void *arg) +{ + + callout_init(&xsoftc.boot_callout, 1); + callout_reset_sbt(&xsoftc.boot_callout, SBT_1MS * xsoftc.boot_delay, 0, + xpt_boot_delay, NULL, 0); +} +SYSINIT(xpt_hw_delay, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, xpt_ch_done, NULL); + +/* + * Now that interrupts are enabled, go find our devices + */ +static void xpt_config(void *arg) { - /* - * Now that interrupts are enabled, go find our devices - */ if (taskqueue_start_threads(&xsoftc.xpt_taskq, 1, PRIBIO, "CAM taskq")) printf("xpt_config: failed to create taskqueue thread.\n"); @@ -5179,9 +5189,7 @@ xpt_config(void *arg) periphdriver_init(1); xpt_hold_boot(); - callout_init(&xsoftc.boot_callout, 1); - callout_reset_sbt(&xsoftc.boot_callout, SBT_1MS * xsoftc.boot_delay, 0, - xpt_boot_delay, NULL, 0); + /* Fire up rescan thread. */ if (kproc_kthread_add(xpt_scanner_thread, NULL, &cam_proc, NULL, 0, 0, "cam", "scanner")) { @@ -5190,31 +5198,38 @@ xpt_config(void *arg) } void +xpt_hold_boot_locked(void) +{ + + if (xsoftc.buses_to_config++ == 0) + root_mount_hold_token("CAM", &xsoftc.xpt_rootmount); +} + +void xpt_hold_boot(void) { + xpt_lock_buses(); - xsoftc.buses_to_config++; + xpt_hold_boot_locked(); xpt_unlock_buses(); } void xpt_release_boot(void) { - xpt_lock_buses(); - xsoftc.buses_to_config--; - if (xsoftc.buses_to_config == 0 && xsoftc.buses_config_done == 0) { - struct xpt_task *task; - xsoftc.buses_config_done = 1; - xpt_unlock_buses(); - /* Call manually because we don't have any buses */ - task = malloc(sizeof(struct xpt_task), M_CAMXPT, M_NOWAIT); - if (task != NULL) { - TASK_INIT(&task->task, 0, xpt_finishconfig_task, task); - taskqueue_enqueue(taskqueue_thread, &task->task); - } - } else - xpt_unlock_buses(); + xpt_lock_buses(); + if (--xsoftc.buses_to_config == 0) { + if (xsoftc.buses_config_done == 0) { + xsoftc.buses_config_done = 1; + xsoftc.buses_to_config++; + TASK_INIT(&xsoftc.boot_task, 0, xpt_finishconfig_task, + NULL); + taskqueue_enqueue(taskqueue_thread, &xsoftc.boot_task); + } else + root_mount_rel(&xsoftc.xpt_rootmount); + } + xpt_unlock_buses(); } /* @@ -5252,10 +5267,7 @@ xpt_finishconfig_task(void *context, int pending) if (!bootverbose) xpt_for_all_devices(xptpassannouncefunc, NULL); - /* Release our hook so that the boot can continue. */ - config_intrhook_disestablish(&xsoftc.xpt_config_hook); - - free(context, M_CAMXPT); + xpt_release_boot(); } cam_status Modified: stable/12/sys/cam/scsi/scsi_enc.c ============================================================================== --- stable/12/sys/cam/scsi/scsi_enc.c Tue Dec 3 16:47:04 2019 (r355336) +++ stable/12/sys/cam/scsi/scsi_enc.c Tue Dec 3 16:48:21 2019 (r355337) @@ -205,10 +205,7 @@ enc_dtor(struct cam_periph *periph) if (enc->enc_vec.softc_cleanup != NULL) enc->enc_vec.softc_cleanup(enc); - if (enc->enc_boot_hold_ch.ich_func != NULL) { - config_intrhook_disestablish(&enc->enc_boot_hold_ch); - enc->enc_boot_hold_ch.ich_func = NULL; - } + root_mount_rel(&enc->enc_rootmount); ENC_FREE(enc); } @@ -835,7 +832,6 @@ enc_daemon(void *arg) cam_periph_lock(enc->periph); while ((enc->enc_flags & ENC_FLAG_SHUTDOWN) == 0) { if (enc->pending_actions == 0) { - struct intr_config_hook *hook; /* * Reset callout and msleep, or @@ -848,11 +844,7 @@ enc_daemon(void *arg) * We've been through our state machine at least * once. Allow the transition to userland. */ - hook = &enc->enc_boot_hold_ch; - if (hook->ich_func != NULL) { - config_intrhook_disestablish(hook); - hook->ich_func = NULL; - } + root_mount_rel(&enc->enc_rootmount); callout_reset(&enc->status_updater, 60*hz, enc_status_updater, enc); @@ -891,22 +883,6 @@ enc_kproc_init(enc_softc_t *enc) cam_periph_release(enc->periph); return (result); } - -/** - * \brief Interrupt configuration hook callback associated with - * enc_boot_hold_ch. - * - * Since interrupts are always functional at the time of enclosure - * configuration, there is nothing to be done when the callback occurs. - * This hook is only registered to hold up boot processing while initial - * eclosure processing occurs. - * - * \param arg The enclosure softc, but currently unused in this callback. - */ -static void -enc_nop_confighook_cb(void *arg __unused) -{ -} static cam_status enc_ctor(struct cam_periph *periph, void *arg) @@ -964,9 +940,7 @@ enc_ctor(struct cam_periph *periph, void *arg) * present. */ if (enc->enc_vec.poll_status != NULL) { - enc->enc_boot_hold_ch.ich_func = enc_nop_confighook_cb; - enc->enc_boot_hold_ch.ich_arg = enc; - config_intrhook_establish(&enc->enc_boot_hold_ch); + root_mount_hold_token(periph->periph_name, &enc->enc_rootmount); } /* Modified: stable/12/sys/cam/scsi/scsi_enc_internal.h ============================================================================== --- stable/12/sys/cam/scsi/scsi_enc_internal.h Tue Dec 3 16:47:04 2019 (r355336) +++ stable/12/sys/cam/scsi/scsi_enc_internal.h Tue Dec 3 16:48:21 2019 (r355337) @@ -163,7 +163,7 @@ struct enc_softc { struct enc_fsm_state *enc_fsm_states; - struct intr_config_hook enc_boot_hold_ch; + struct root_hold_token enc_rootmount; #define ENC_ANNOUNCE_SZ 400 char announce_buf[ENC_ANNOUNCE_SZ];