Date: Sun, 18 Jul 2004 06:29:45 GMT From: Scott Long <scottl@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 57604 for review Message-ID: <200407180629.i6I6Tj4b077527@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=57604 Change 57604 by scottl@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407180629.i6I6Tj4b077527>