svn commit: r203892 - stable/8/sys/cam

Alexander Motin mav at FreeBSD.org
Sun Feb 14 19:48:53 UTC 2010


Author: mav
Date: Sun Feb 14 19:48:53 2010
New Revision: 203892
URL: http://svn.freebsd.org/changeset/base/203892

Log:
  MFC r203386:
  Change the way in which fake async events generated. Do not use
  taskqueue for lock decoupling, as it causes unwanted races.

Modified:
  stable/8/sys/cam/cam_xpt.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/netinet/   (props changed)

Modified: stable/8/sys/cam/cam_xpt.c
==============================================================================
--- stable/8/sys/cam/cam_xpt.c	Sun Feb 14 19:46:54 2010	(r203891)
+++ stable/8/sys/cam/cam_xpt.c	Sun Feb 14 19:48:53 2010	(r203892)
@@ -2392,9 +2392,7 @@ xptsetasyncfunc(struct cam_ed *device, v
 {
 	struct cam_path path;
 	struct ccb_getdev cgd;
-	struct async_node *cur_entry;
-
-	cur_entry = (struct async_node *)arg;
+	struct ccb_setasync *csa = (struct ccb_setasync *)arg;
 
 	/*
 	 * Don't report unconfigured devices (Wildcard devs,
@@ -2413,7 +2411,7 @@ xptsetasyncfunc(struct cam_ed *device, v
 	xpt_setup_ccb(&cgd.ccb_h, &path, CAM_PRIORITY_NORMAL);
 	cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 	xpt_action((union ccb *)&cgd);
-	cur_entry->callback(cur_entry->callback_arg,
+	csa->callback(csa->callback_arg,
 			    AC_FOUND_DEVICE,
 			    &path, &cgd);
 	xpt_release_path(&path);
@@ -2426,9 +2424,7 @@ xptsetasyncbusfunc(struct cam_eb *bus, v
 {
 	struct cam_path path;
 	struct ccb_pathinq cpi;
-	struct async_node *cur_entry;
-
-	cur_entry = (struct async_node *)arg;
+	struct ccb_setasync *csa = (struct ccb_setasync *)arg;
 
 	xpt_compile_path(&path, /*periph*/NULL,
 			 bus->sim->path_id,
@@ -2437,7 +2433,7 @@ xptsetasyncbusfunc(struct cam_eb *bus, v
 	xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 	cpi.ccb_h.func_code = XPT_PATH_INQ;
 	xpt_action((union ccb *)&cpi);
-	cur_entry->callback(cur_entry->callback_arg,
+	csa->callback(csa->callback_arg,
 			    AC_PATH_REGISTERED,
 			    &path, &cpi);
 	xpt_release_path(&path);
@@ -2445,35 +2441,6 @@ xptsetasyncbusfunc(struct cam_eb *bus, v
 	return(1);
 }
 
-static void
-xpt_action_sasync_cb(void *context, int pending)
-{
-	struct async_node *cur_entry;
-	struct xpt_task *task;
-	uint32_t added;
-
-	task = (struct xpt_task *)context;
-	cur_entry = (struct async_node *)task->data1;
-	added = task->data2;
-
-	if ((added & AC_FOUND_DEVICE) != 0) {
-		/*
-		 * Get this peripheral up to date with all
-		 * the currently existing devices.
-		 */
-		xpt_for_all_devices(xptsetasyncfunc, cur_entry);
-	}
-	if ((added & AC_PATH_REGISTERED) != 0) {
-		/*
-		 * Get this peripheral up to date with all
-		 * the currently existing busses.
-		 */
-		xpt_for_all_busses(xptsetasyncbusfunc, cur_entry);
-	}
-
-	free(task, M_CAMXPT);
-}
-
 void
 xpt_action(union ccb *start_ccb)
 {
@@ -2885,11 +2852,12 @@ xpt_action_default(union ccb *start_ccb)
 			if (csa->event_enable == 0) {
 				SLIST_REMOVE(async_head, cur_entry,
 					     async_node, links);
-				csa->ccb_h.path->device->refcount--;
+				xpt_release_device(csa->ccb_h.path->device);
 				free(cur_entry, M_CAMXPT);
 			} else {
 				cur_entry->event_enable = csa->event_enable;
 			}
+			csa->event_enable = added;
 		} else {
 			cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT,
 					   M_NOWAIT);
@@ -2901,29 +2869,8 @@ xpt_action_default(union ccb *start_ccb)
 			cur_entry->callback_arg = csa->callback_arg;
 			cur_entry->callback = csa->callback;
 			SLIST_INSERT_HEAD(async_head, cur_entry, links);
-			csa->ccb_h.path->device->refcount++;
+			xpt_acquire_device(csa->ccb_h.path->device);
 		}
-
-		/*
-		 * Need to decouple this operation via a taqskqueue so that
-		 * the locking doesn't become a mess.
-		 */
-		if ((added & (AC_FOUND_DEVICE | AC_PATH_REGISTERED)) != 0) {
-			struct xpt_task *task;
-
-			task = malloc(sizeof(struct xpt_task), M_CAMXPT,
-				      M_NOWAIT);
-			if (task == NULL) {
-				csa->ccb_h.status = CAM_RESRC_UNAVAIL;
-				break;
-			}
-
-			TASK_INIT(&task->task, 0, xpt_action_sasync_cb, task);
-			task->data1 = cur_entry;
-			task->data2 = added;
-			taskqueue_enqueue(taskqueue_thread, &task->task);
-		}
-
 		start_ccb->ccb_h.status = CAM_REQ_CMP;
 		break;
 	}
@@ -4823,6 +4770,23 @@ xpt_register_async(int event, ac_callbac
 	if (xptpath) {
 		xpt_free_path(path);
 		mtx_unlock(&xsoftc.xpt_lock);
+
+		if ((status == CAM_REQ_CMP) &&
+		    (csa.event_enable & AC_FOUND_DEVICE)) {
+			/*
+			 * Get this peripheral up to date with all
+			 * the currently existing devices.
+			 */
+			xpt_for_all_devices(xptsetasyncfunc, &csa);
+		}
+		if ((status == CAM_REQ_CMP) &&
+		    (csa.event_enable & AC_PATH_REGISTERED)) {
+			/*
+			 * Get this peripheral up to date with all
+			 * the currently existing busses.
+			 */
+			xpt_for_all_busses(xptsetasyncbusfunc, &csa);
+		}
 	}
 	return (status);
 }


More information about the svn-src-all mailing list