Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Aug 2013 10:17:21 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r254359 - projects/camlock/sys/cam
Message-ID:  <201308151017.r7FAHLCH066173@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Aug 15 10:17:20 2013
New Revision: 254359
URL: http://svnweb.freebsd.org/changeset/base/254359

Log:
  Take SIM lock when executing async handler if lock was owned when registered.
  This should be partial workaround for rare SIMs that want to receive events.

Modified:
  projects/camlock/sys/cam/cam_xpt.c
  projects/camlock/sys/cam/cam_xpt.h

Modified: projects/camlock/sys/cam/cam_xpt.c
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.c	Thu Aug 15 08:21:00 2013	(r254358)
+++ projects/camlock/sys/cam/cam_xpt.c	Thu Aug 15 10:17:20 2013	(r254359)
@@ -2822,6 +2822,8 @@ call_sim:
 				break;
 			}
 			cur_entry->event_enable = csa->event_enable;
+			cur_entry->event_lock =
+			    mtx_owned(path->bus->sim->mtx) ? 1 : 0;
 			cur_entry->callback_arg = csa->callback_arg;
 			cur_entry->callback = csa->callback;
 			SLIST_INSERT_HEAD(async_head, cur_entry, links);
@@ -4102,6 +4104,7 @@ xpt_async_bcast(struct async_list *async
 		struct cam_path *path, void *async_arg)
 {
 	struct async_node *cur_entry;
+	int lock;
 
 	cur_entry = SLIST_FIRST(async_head);
 	while (cur_entry != NULL) {
@@ -4112,10 +4115,16 @@ xpt_async_bcast(struct async_list *async
 		 * can delete its async callback entry.
 		 */
 		next_entry = SLIST_NEXT(cur_entry, links);
-		if ((cur_entry->event_enable & async_code) != 0)
+		if ((cur_entry->event_enable & async_code) != 0) {
+			lock = cur_entry->event_lock;
+			if (lock)
+				CAM_SIM_LOCK(path->device->sim);
 			cur_entry->callback(cur_entry->callback_arg,
 					    async_code, path,
 					    async_arg);
+			if (lock)
+				CAM_SIM_UNLOCK(path->device->sim);
+		}
 		cur_entry = next_entry;
 	}
 }

Modified: projects/camlock/sys/cam/cam_xpt.h
==============================================================================
--- projects/camlock/sys/cam/cam_xpt.h	Thu Aug 15 08:21:00 2013	(r254358)
+++ projects/camlock/sys/cam/cam_xpt.h	Thu Aug 15 10:17:20 2013	(r254359)
@@ -55,6 +55,7 @@ struct cam_path;
 struct async_node {
 	SLIST_ENTRY(async_node)	links;
 	u_int32_t	event_enable;	/* Async Event enables */
+	u_int32_t	event_lock;	/* Take SIM lock for handlers. */
 	void		(*callback)(void *arg, u_int32_t code,
 				    struct cam_path *path, void *args);
 	void		*callback_arg;



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