Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 Oct 2015 10:40:15 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r288773 - stable/10/sys/cam/ctl
Message-ID:  <201510051040.t95AeFRB069327@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Oct  5 10:40:15 2015
New Revision: 288773
URL: https://svnweb.freebsd.org/changeset/base/288773

Log:
  MFC r287957: Kill HA link and shutdown the threads on shutdown.

Modified:
  stable/10/sys/cam/ctl/ctl.c
  stable/10/sys/cam/ctl/ctl_ha.c
  stable/10/sys/cam/ctl/ctl_ha.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/cam/ctl/ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl.c	Mon Oct  5 10:39:21 2015	(r288772)
+++ stable/10/sys/cam/ctl/ctl.c	Mon Oct  5 10:40:15 2015	(r288773)
@@ -1583,13 +1583,12 @@ ctl_shutdown(void)
 	softc = (struct ctl_softc *)control_softc;
 
 	if (softc->is_single == 0) {
+		ctl_ha_msg_shutdown(softc);
 		if (ctl_ha_msg_deregister(CTL_HA_CHAN_CTL)
-		    != CTL_HA_STATUS_SUCCESS) {
-			printf("ctl_shutdown: ctl_ha_msg_deregister failed.\n");
-		}
-		if (ctl_ha_msg_shutdown(softc) != CTL_HA_STATUS_SUCCESS) {
-			printf("ctl_shutdown: ctl_ha_msg_shutdown failed.\n");
-		}
+		    != CTL_HA_STATUS_SUCCESS)
+			printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
+		if (ctl_ha_msg_destroy(softc) != CTL_HA_STATUS_SUCCESS)
+			printf("%s: ctl_ha_msg_destroy failed.\n", __func__);
 		ctl_frontend_deregister(&ha_frontend);
 	}
 

Modified: stable/10/sys/cam/ctl/ctl_ha.c
==============================================================================
--- stable/10/sys/cam/ctl/ctl_ha.c	Mon Oct  5 10:39:21 2015	(r288772)
+++ stable/10/sys/cam/ctl/ctl_ha.c	Mon Oct  5 10:40:15 2015	(r288773)
@@ -155,6 +155,8 @@ struct ha_softc {
 	int		 ha_receiving;
 	int		 ha_wakeup;
 	int		 ha_disconnect;
+	int		 ha_shutdown;
+	eventhandler_tag ha_shutdown_eh;
 	TAILQ_HEAD(, ctl_ha_dt_req) ha_dts;
 } ha_softc;
 
@@ -568,10 +570,12 @@ ctl_ha_conn_thread(void *arg)
 	int error;
 
 	while (1) {
-		if (softc->ha_disconnect) {
+		if (softc->ha_disconnect || softc->ha_shutdown) {
 			ctl_ha_close(softc);
 			ctl_ha_lclose(softc);
 			softc->ha_disconnect = 0;
+			if (softc->ha_shutdown)
+				break;
 		} else if (softc->ha_so != NULL &&
 		    (softc->ha_so->so_error ||
 		     softc->ha_so->so_rcv.sb_state & SBS_CANTRCVMORE))
@@ -614,6 +618,11 @@ ctl_ha_conn_thread(void *arg)
 		softc->ha_wakeup = 0;
 		mtx_unlock(&softc->ha_lock);
 	}
+	mtx_lock(&softc->ha_lock);
+	softc->ha_shutdown = 2;
+	wakeup(&softc->ha_wakeup);
+	mtx_unlock(&softc->ha_lock);
+	kthread_exit();
 }
 
 static int
@@ -936,6 +945,8 @@ ctl_ha_msg_init(struct ctl_softc *ctl_so
 		mtx_destroy(&softc->ha_lock);
 		return (CTL_HA_STATUS_ERROR);
 	}
+	softc->ha_shutdown_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync,
+	    ctl_ha_msg_shutdown, ctl_softc, SHUTDOWN_PRI_FIRST);
 	SYSCTL_ADD_PROC(&ctl_softc->sysctl_ctx,
 	    SYSCTL_CHILDREN(ctl_softc->sysctl_tree),
 	    OID_AUTO, "ha_peer", CTLTYPE_STRING | CTLFLAG_RWTUN,
@@ -949,14 +960,40 @@ ctl_ha_msg_init(struct ctl_softc *ctl_so
 	return (CTL_HA_STATUS_SUCCESS);
 };
 
-ctl_ha_status
+void
 ctl_ha_msg_shutdown(struct ctl_softc *ctl_softc)
 {
 	struct ha_softc *softc = &ha_softc;
 
-	if (ctl_ha_msg_deregister(CTL_HA_CHAN_DATA) != CTL_HA_STATUS_SUCCESS) {
-		printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
+	/* Disconnect and shutdown threads. */
+	mtx_lock(&softc->ha_lock);
+	if (softc->ha_shutdown < 2) {
+		softc->ha_shutdown = 1;
+		softc->ha_wakeup = 1;
+		wakeup(&softc->ha_wakeup);
+		while (softc->ha_shutdown < 2) {
+			msleep(&softc->ha_wakeup, &softc->ha_lock, 0,
+			    "shutdown", hz);
+		}
 	}
+	mtx_unlock(&softc->ha_lock);
+};
+
+ctl_ha_status
+ctl_ha_msg_destroy(struct ctl_softc *ctl_softc)
+{
+	struct ha_softc *softc = &ha_softc;
+
+	if (softc->ha_shutdown_eh != NULL) {
+		EVENTHANDLER_DEREGISTER(shutdown_pre_sync,
+		    softc->ha_shutdown_eh);
+		softc->ha_shutdown_eh = NULL;
+	}
+
+	ctl_ha_msg_shutdown(ctl_softc);	/* Just in case. */
+
+	if (ctl_ha_msg_deregister(CTL_HA_CHAN_DATA) != CTL_HA_STATUS_SUCCESS)
+		printf("%s: ctl_ha_msg_deregister failed.\n", __func__);
 
 	mtx_destroy(&softc->ha_lock);
 	return (CTL_HA_STATUS_SUCCESS);

Modified: stable/10/sys/cam/ctl/ctl_ha.h
==============================================================================
--- stable/10/sys/cam/ctl/ctl_ha.h	Mon Oct  5 10:39:21 2015	(r288772)
+++ stable/10/sys/cam/ctl/ctl_ha.h	Mon Oct  5 10:40:15 2015	(r288773)
@@ -109,7 +109,8 @@ struct ctl_ha_dt_req {
 
 struct ctl_softc;
 ctl_ha_status ctl_ha_msg_init(struct ctl_softc *softc);
-ctl_ha_status ctl_ha_msg_shutdown(struct ctl_softc *softc);
+void ctl_ha_msg_shutdown(struct ctl_softc *softc);
+ctl_ha_status ctl_ha_msg_destroy(struct ctl_softc *softc);
 
 typedef void (*ctl_evt_handler)(ctl_ha_channel channel, ctl_ha_event event,
 				int param);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201510051040.t95AeFRB069327>