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