From owner-svn-src-all@freebsd.org Fri Nov 22 18:39:52 2019 Return-Path: Delivered-To: svn-src-all@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 779A61BDFE0; Fri, 22 Nov 2019 18:39:52 +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 47KQG02Ttcz44qh; Fri, 22 Nov 2019 18:39:52 +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 389E027B13; Fri, 22 Nov 2019 18:39:52 +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 xAMIdqNS056575; Fri, 22 Nov 2019 18:39:52 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xAMIdpMa056572; Fri, 22 Nov 2019 18:39:51 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201911221839.xAMIdpMa056572@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Fri, 22 Nov 2019 18:39:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355010 - in head/sys/cam: . scsi X-SVN-Group: head X-SVN-Commit-Author: mav X-SVN-Commit-Paths: in head/sys/cam: . scsi X-SVN-Commit-Revision: 355010 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Nov 2019 18:39:52 -0000 Author: mav Date: Fri Nov 22 18:39:51 2019 New Revision: 355010 URL: https://svnweb.freebsd.org/changeset/base/355010 Log: 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. MFC after: 2 weeks Sponsored by: iXsystems, Inc. Modified: head/sys/cam/cam_xpt.c head/sys/cam/scsi/scsi_enc.c head/sys/cam/scsi/scsi_enc_internal.h Modified: head/sys/cam/cam_xpt.c ============================================================================== --- head/sys/cam/cam_xpt.c Fri Nov 22 18:18:36 2019 (r355009) +++ head/sys/cam/cam_xpt.c Fri Nov 22 18:39:51 2019 (r355010) @@ -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: head/sys/cam/scsi/scsi_enc.c ============================================================================== --- head/sys/cam/scsi/scsi_enc.c Fri Nov 22 18:18:36 2019 (r355009) +++ head/sys/cam/scsi/scsi_enc.c Fri Nov 22 18:39:51 2019 (r355010) @@ -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: head/sys/cam/scsi/scsi_enc_internal.h ============================================================================== --- head/sys/cam/scsi/scsi_enc_internal.h Fri Nov 22 18:18:36 2019 (r355009) +++ head/sys/cam/scsi/scsi_enc_internal.h Fri Nov 22 18:39:51 2019 (r355010) @@ -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];