PERFORCE change 57604 for review

Scott Long scottl at FreeBSD.org
Sat Jul 17 23:29:46 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=57604

Change 57604 by scottl at scottl-junior on 2004/07/18 06:29:15

	Move the CCB allocator to use UMA instead of malloc.  This mainly
	affects xpt_alloc_ccb/xpt_free_ccb, but many places were doing their
	own allocation of ccbs and then passing them to the XPT for ownership,
	so they are changed to use xpt_alloc_ccb also.
	
	This gives about a 2-3% performance improvement under SMP.  It seems
	to take a while to warm up the UMA caches, and it doesn't perform
	nearly as well in it's current form as when you pre-allocate a
	significant number of objects.  However, Doing such over-preallocation
	is extremely wasteful of memory.
	
	There was a bit of code to try to dynamically grow and shrink the
	ccb pool.  This largely remains, but provides no direct pressure to
	UMA.  Small tests involving dynamically growing the UMA zone in
	response to this pressure provided neglible benefits.  We instead rely
	on UMA's own mechanisms for adjusting the zone size.
	
	Furture optimizaters might want to look at making use of the ctor/dtors
	that UMA provides.  It would also be useful to tie the pools to
	per-CPU and/or per-interface zones to achieve better locality and
	fewer UMA locks in the slow path.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#5 edit
.. //depot/projects/scottl-camlock/src/sys/cam/cam_xpt_periph.h#2 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_low.c#2 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_pass.c#3 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_probe.c#3 edit
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_targ_bh.c#2 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt.c#5 (text+ko) ====

@@ -42,6 +42,7 @@
 #include <sys/md5.h>
 #include <sys/interrupt.h>
 #include <sys/sbuf.h>
+#include <vm/uma.h>
 
 #ifdef PC98
 #include <pc98/pc98/pc98_machdep.h>	/* geometry translation */
@@ -482,6 +483,8 @@
 
 struct cam_periph *xpt_periph;
 
+static uma_zone_t ccb_zone;
+
 static periph_init_t xpt_periph_init;
 
 static struct periph_driver xpt_driver =
@@ -874,7 +877,7 @@
 		case XPT_ENG_INQ:
 		case XPT_SCAN_LUN:
 
-			ccb = xpt_alloc_ccb();
+			ccb = xpt_alloc_ccb(M_WAITOK);
 
 			/*
 			 * Create a path using the bus, target, and lun the
@@ -1206,6 +1209,10 @@
 	SLIST_INIT(&ccb_freeq);
 	STAILQ_INIT(&highpowerq);
 
+	/* Create the CCB zone */
+	ccb_zone = uma_zcreate("CAM CCB Pool", sizeof(union ccb), NULL, NULL,
+				NULL, NULL, 0, 0);
+
 	/*
 	 * The xpt layer is, itself, the equivelent of a SIM.
 	 * Allow 16 ccbs in the ccb pool for it.  This should
@@ -1222,6 +1229,7 @@
 				/*max_tagged_dev_transactions*/0,
 				devq);
 	xpt_max_ccbs = 16;
+	uma_prealloc(ccb_zone, xpt_max_ccbs);
 				
 	xpt_bus_register(xpt_sim, /*bus #*/0);
 
@@ -4685,20 +4693,18 @@
 }
 
 union ccb *
-xpt_alloc_ccb()
+xpt_alloc_ccb(int wait)
 {
 	union ccb *new_ccb;
 
-	GIANT_REQUIRED;
-
-	new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_WAITOK);
+	new_ccb = uma_zalloc(ccb_zone, wait);
 	return (new_ccb);
 }
 
 void
 xpt_free_ccb(union ccb *free_ccb)
 {
-	free(free_ccb, M_DEVBUF);
+	uma_zfree(ccb_zone, free_ccb);
 }
 
 
@@ -4720,7 +4726,7 @@
 
 	s = splsoftcam();
 	if ((new_ccb = (union ccb *)SLIST_FIRST(&ccb_freeq)) == NULL) {
-		new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_NOWAIT);
+		new_ccb = xpt_alloc_ccb(M_NOWAIT);
                 if (new_ccb == NULL) {
 			splx(s);
 			return (NULL);
@@ -5031,7 +5037,7 @@
 		u_int	initiator_id;
 
 		/* Find out the characteristics of the bus */
-		work_ccb = xpt_alloc_ccb();
+		work_ccb = xpt_alloc_ccb(M_WAITOK);
 		xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
 			      request_ccb->ccb_h.pinfo.priority);
 		work_ccb->ccb_h.func_code = XPT_PATH_INQ;
@@ -5086,7 +5092,7 @@
 				       status);
 				break;
 			}
-			work_ccb = xpt_alloc_ccb();
+			work_ccb = xpt_alloc_ccb(M_WAITOK);
 			xpt_setup_ccb(&work_ccb->ccb_h, path,
 				      request_ccb->ccb_h.pinfo.priority);
 			work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
@@ -5896,7 +5902,7 @@
 		cam_status status;
 		int can_negotiate;
 
-		work_ccb = xpt_alloc_ccb();
+		work_ccb = xpt_alloc_ccb(M_WAITOK);
 		if ((status = xpt_create_path(&path, xpt_periph, bus->path_id,
 					      CAM_TARGET_WILDCARD,
 					      CAM_LUN_WILDCARD)) !=CAM_REQ_CMP){

==== //depot/projects/scottl-camlock/src/sys/cam/cam_xpt_periph.h#2 (text+ko) ====

@@ -38,7 +38,7 @@
 /* Functions accessed by the peripheral drivers */
 #ifdef _KERNEL
 void		xpt_polled_action(union ccb *ccb);
-union ccb	*xpt_alloc_ccb(void);
+union ccb	*xpt_alloc_ccb(int wait);
 void		xpt_free_ccb(union ccb *free_ccb);
 void		xpt_release_ccb(union ccb *released_ccb);
 void		xpt_schedule(struct cam_periph *perph, u_int32_t new_priority);

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_low.c#2 (text+ko) ====

@@ -955,7 +955,7 @@
 {
 
 	xpt_free_path(ccb->ccb_h.path);
-	free(ccb, M_DEVBUF);
+	xpt_free_ccb(ccb);
 }
 
 static void
@@ -963,7 +963,7 @@
 	struct scsi_low_softc *slp;
 {
   	struct cam_path *path;
-	union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
+	union ccb *ccb = xpt_alloc_ccb(M_WAITOK);
 	cam_status status;
 
 	bzero(ccb, sizeof(union ccb));

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_pass.c#3 (text+ko) ====

@@ -494,7 +494,7 @@
 						inccb->ccb_h.pinfo.priority);
 			ccb_malloced = 0;
 		} else {
-			ccb = xpt_alloc_ccb();
+			ccb = xpt_alloc_ccb(M_WAITOK);
 
 			if (ccb != NULL)
 				xpt_setup_ccb(&ccb->ccb_h, periph->path,

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_probe.c#3 (text+ko) ====

@@ -820,7 +820,7 @@
 	}
 
 	if (request_ccb == NULL) {
-		request_ccb = malloc(sizeof(union ccb), M_TEMP, M_NOWAIT);
+		request_ccb = xpt_alloc_ccb(M_NOWAIT);
 		if (request_ccb == NULL) {
 			xpt_print_path(path);
 			printf("xpt_scan_lun: can't allocate CCB, can't "
@@ -832,7 +832,7 @@
 			xpt_print_path(path);
 			printf("xpt_scan_lun: can't allocate path, can't "
 			       "continue\n");
-			free(request_ccb, M_TEMP);
+			xpt_free_ccb(request_ccb);
 			return;
 		}
 		status = xpt_compile_path(new_path, xpt_periph,
@@ -844,7 +844,7 @@
 			xpt_print_path(path);
 			printf("xpt_scan_lun: can't compile path, can't "
 			       "continue\n");
-			free(request_ccb, M_TEMP);
+			xpt_free_ccb(request_ccb);
 			free(new_path, M_TEMP);
 			return;
 		}
@@ -886,6 +886,6 @@
 {
 	xpt_release_path(done_ccb->ccb_h.path);
 	free(done_ccb->ccb_h.path, M_TEMP);
-	free(done_ccb, M_TEMP);
+	xpt_free_ccb(done_ccb);
 }
 

==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_targ_bh.c#2 (text+ko) ====

@@ -576,7 +576,7 @@
 		if (softc->state == TARGBH_STATE_TEARDOWN
 		 || atio->ccb_h.status == CAM_REQ_ABORTED) {
 			targbhfreedescr(descr);
-			free(done_ccb, M_DEVBUF);
+			xpt_free_ccb(done_ccb);
 			return;
 		}
 
@@ -737,7 +737,7 @@
 		if (softc->state == TARGBH_STATE_TEARDOWN
 		 || done_ccb->ccb_h.status == CAM_REQ_ABORTED) {
 			printf("Freed an immediate notify\n");
-			free(done_ccb, M_DEVBUF);
+			xpt_free_ccb(done_ccb);
 		} else {
 			/* Requeue for another immediate event */
 			xpt_action(done_ccb);


More information about the p4-projects mailing list