From owner-freebsd-current@FreeBSD.ORG Fri Aug 29 21:04:00 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D3E9016A4BF; Fri, 29 Aug 2003 21:04:00 -0700 (PDT) Received: from panzer.kdm.org (panzer.kdm.org [216.160.178.169]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9BE0643FEC; Fri, 29 Aug 2003 21:03:58 -0700 (PDT) (envelope-from ken@panzer.kdm.org) Received: from panzer.kdm.org (localhost [127.0.0.1]) by panzer.kdm.org (8.12.9/8.12.5) with ESMTP id h7U43wYU042947; Fri, 29 Aug 2003 22:03:58 -0600 (MDT) (envelope-from ken@panzer.kdm.org) Received: (from ken@localhost) by panzer.kdm.org (8.12.9/8.12.5/Submit) id h7U43v2f042946; Fri, 29 Aug 2003 22:03:57 -0600 (MDT) (envelope-from ken) Date: Fri, 29 Aug 2003 22:03:57 -0600 From: "Kenneth D. Merry" To: current@FreeBSD.org Message-ID: <20030830040357.GA42770@panzer.kdm.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="NzB8fVQJ5HfG6fxh" Content-Disposition: inline User-Agent: Mutt/1.4.1i cc: phk@FreeBSD.org Subject: need some debugging help X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 30 Aug 2003 04:04:00 -0000 --NzB8fVQJ5HfG6fxh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I've been working on a set of patches to remove the sysctl variable creation from interrupt context in the cd(4) and da(4) drivers. To fix the problem, I've created a new taskqueue that runs in a thread context, instead of inside a software interrupt like the current task queues. (The eventual fix will involve moving the CAM probe inside a thread; this will provide a more temporary solution that will hopefully also work on -stable, until we can change the CAM probe code.) I think I have everything setup correctly, but I keep getting panics inside the GEOM code with these patches. (Memory modified after free.) I don't know whether I've just exposed some race condition, or whether I've done something wrong. I've seen several different panics, all with the same root cause (memory modified after free), and with two different previous memory pools -- geom and devbuf. ========================================================================== SMP: AP CPU #1 Launched! Memory modified after free 0xcbd4f800(124) panic: Most recently used by GEOM cpuid = 0; lapic.id = 00000000 Debugger("panic") Stopped at Debugger+0x55: xchgl %ebx,in_Debugger.0 db> trace Debugger(c03e974d,0,c03fb4d8,e5e45934,100) at Debugger+0x55 panic(c03fb4d8,c03e55db,7c,c083ac14,c083ac00) at panic+0x15f mtrash_ctor(cbd4f800,80,0,57a,cbd4f800) at mtrash_ctor+0x5d uma_zalloc_arg(c083ac00,0,102,e5e4599c,e5e4599c) at uma_zalloc_arg+0x1e4 malloc(5b,c042fae0,102,1,c02756e4) at malloc+0xd3 g_new_providerf(cbda62c0,cbd7b130,e5e45a3c,1,1) at g_new_providerf+0xa3 g_slice_config(cbda62c0,2,1,0,0) at g_slice_config+0x259 g_bsd_modify(cbda62c0,cbd7712c,e5e45c8c,10,cbd77000) at g_bsd_modify+0x382 g_bsd_taste(c0470480,cbda5780,0,159,cbda5700) at g_bsd_taste+0x2c4 g_new_provider_event(cbda5780,0,c03e52b7,b3,66666667) at g_new_provider_event+0xad one_event(e5e45d0c,c021cd85,c0485fb4,0,4c) at one_event+0x218 g_run_events(c0485fb4,0,4c,c03d7a28,a) at g_run_events+0x15 g_event_procbody(0,e5e45d48,c03e738b,314,34df1a6d) at g_event_procbody+0x45 fork_exit(c021cd40,0,e5e45d48) at fork_exit+0xcf fork_trampoline() at fork_trampoline+0x8 --- trap 0x1, eip = 0, esp = 0xe5e45d7c, ebp = 0 --- db> panic ========================================================================== SMP: AP CPU #1 Launched! Memory modified after free 0xcbd4f600(124) panic: Most recently used by devbuf cpuid = 0; lapic.id = 00000000 Debugger("panic") Stopped at Debugger+0x55: xchgl %ebx,in_Debugger.0 db> trace Debugger(c03e974d,0,c03fb4d8,e5e45af0,100) at Debugger+0x55 panic(c03fb4d8,c03e7f50,7c,c083ac14,c083ac00) at panic+0x15f mtrash_ctor(cbd4f600,80,0,57a,cbd4f600) at mtrash_ctor+0x5d uma_zalloc_arg(c083ac00,0,102,e5e45b58,e5e45b58) at uma_zalloc_arg+0x1e4 malloc(5a,c042fae0,102,1,c02756e4) at malloc+0xd3 g_new_providerf(cbda74c0,cb9b0d90,e5e45bf8,1,1) at g_new_providerf+0xa3 g_slice_config(cbda74c0,0,1,7e00,0) at g_slice_config+0x259 g_mbr_modify(cbda74c0,cb9d3800,cbd5b200,123,0) at g_mbr_modify+0x247 g_mbr_taste(c0470560,cbd4ee80,0,159,cbd4f580) at g_mbr_taste+0x1be g_new_provider_event(cbd4ee80,0,c03e52b7,b3,66666667) at g_new_provider_event+0xad one_event(e5e45d0c,c021cd85,c0485fb4,0,4c) at one_event+0x218 g_run_events(c0485fb4,0,4c,c03d7a28,a) at g_run_events+0x15 g_event_procbody(0,e5e45d48,c03e738b,314,34df1a6d) at g_event_procbody+0x45 fork_exit(c021cd40,0,e5e45d48) at fork_exit+0xcf fork_trampoline() at fork_trampoline+0x8 --- trap 0x1, eip = 0, esp = 0xe5e45d7c, ebp = 0 --- db> panic ========================================================================== Memory modified after free 0xcbd4f600(124) panic: Most recently used by devbuf cpuid = 0; lapic.id = 00000000 Debugger("panic") Stopped at Debugger+0x55: xchgl %ebx,in_Debugger.0 db> trace Debugger(c03e974d,0,c03fb4d8,e5e45bbc,100) at Debugger+0x55 panic(c03fb4d8,c03e7f50,7c,c083ac14,c083ac00) at panic+0x15f mtrash_ctor(cbd4f600,80,0,57a,cbd4f600) at mtrash_ctor+0x5d uma_zalloc_arg(c083ac00,0,102,fe,cbd6b800) at uma_zalloc_arg+0x1e4 malloc(60,c042fae0,102,cbd59240,c0470560) at malloc+0xd3 g_slice_alloc(4,214,cbd4f4d4,1c2,e5e45c9c) at g_slice_alloc+0x7e g_slice_new(c0470560,4,cbd4f480,e5e45c98,e5e45c9c) at g_slice_new+0x6f g_mbr_taste(c0470560,cbd4f480,0,159,cbd4f580) at g_mbr_taste+0x90 g_new_provider_event(cbd4f480,0,c03e52b7,b3,66666667) at g_new_provider_event+0xad one_event(e5e45d0c,c021cd85,c0485fb4,0,4c) at one_event+0x218 g_run_events(c0485fb4,0,4c,c03d7a28,a) at g_run_events+0x15 g_event_procbody(0,e5e45d48,c03e738b,314,34df1a6d) at g_event_procbody+0x45 fork_exit(c021cd40,0,e5e45d48) at fork_exit+0xcf fork_trampoline() at fork_trampoline+0x8 --- trap 0x1, eip = 0, esp = 0xe5e45d7c, ebp = 0 --- db> ========================================================================== SMP: AP CPU #1 Launched! Memory modified after free 0xcbd4f600(124) panic: Most recently used by devbuf cpuid = 0; lapic.id = 00000000 Debugger("panic") Stopped at Debugger+0x55: xchgl %ebx,in_Debugger.0 db> trace Debugger(c03e974d,0,c03fb4d8,e5e45aa8,100) at Debugger+0x55 panic(c03fb4d8,c03e7f50,7c,c083ac14,c083ac00) at panic+0x15f mtrash_ctor(cbd4f600,80,0,57a,cbd4f600) at mtrash_ctor+0x5d uma_zalloc_arg(c083ac00,0,102,5c,cbd4f900) at uma_zalloc_arg+0x1e4 malloc(64,c042fae0,102,cbd4f900,2) at malloc+0xd3 g_post_event_x(c021ea70,cbd4f900,2,0,e5e45b6c) at g_post_event_x+0x54 g_post_event(c021ea70,cbd4f900,2,cbd4f900,0) at g_post_event+0x45 g_new_providerf(cbda3540,cb9b0b20,e5e45bf8,1,1) at g_new_providerf+0x151 g_slice_config(cbda3540,0,1,7e00,0) at g_slice_config+0x259 g_mbr_modify(cbda3540,cbd6c400,cbd73000,123,0) at g_mbr_modify+0x247 g_mbr_taste(c0470560,cbd4f700,0,159,cbd4f780) at g_mbr_taste+0x1be g_new_provider_event(cbd4f700,0,c03e52b7,b3,66666667) at g_new_provider_event+0xad one_event(e5e45d0c,c021cd85,c0485fb4,0,4c) at one_event+0x218 g_run_events(c0485fb4,0,4c,c03d7a28,a) at g_run_events+0x15 g_event_procbody(0,e5e45d48,c03e738b,314,34df1a6d) at g_event_procbody+0x45 fork_exit(c021cd40,0,e5e45d48) at fork_exit+0xcf fork_trampoline() at fork_trampoline+0x8 --- trap 0x1, eip = 0, esp = 0xe5e45d7c, ebp = 0 --- ========================================================================== Since the panics involved either M_DEVBUF or M_GEOM, I removed all M_DEVBUF mallocs from the cd(4) and da(4) drivers. (None of the other affected code used M_DEVBUF; I created new malloc types for the cd(4) and da(4) drivers.) The problem didn't change. (Other than the exact place in GEOM that triggered the malloc that caught the problem.) Anyway, I've attached the patch in question. If someone could tell me what (if anything) I'm doing wrong, I'd appreciate it! Thanks, Ken -- Kenneth Merry ken@kdm.org --NzB8fVQJ5HfG6fxh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cam.sysctl.20030829" ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c#39 - /usr/home/ken/perforce2/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c ==== *** /tmp/tmp.285.0 Fri Aug 29 21:34:15 2003 --- /usr/home/ken/perforce2/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c Fri Aug 29 21:16:37 2003 *************** *** 62,67 **** --- 62,68 ---- #include #include #include + #include #include #include *************** *** 154,159 **** --- 155,161 ---- eventhandler_tag clonetag; int minimum_command_size; int outstanding_cmds; + struct task sysctl_task; struct sysctl_ctx_list sysctl_ctx; struct sysctl_oid *sysctl_tree; STAILQ_HEAD(, cd_mode_params) mode_queue; *************** *** 311,316 **** --- 313,320 ---- #define CHANGER_MAX_BUSY_SECONDS 15 #endif + MALLOC_DEFINE(M_CAM_CD, "cdbuffers", "Buffers for cd(4)"); + static int changer_min_busy_seconds = CHANGER_MIN_BUSY_SECONDS; static int changer_max_busy_seconds = CHANGER_MAX_BUSY_SECONDS; *************** *** 524,536 **** changer_links); xpt_print_path(periph->path); printf("removing changer entry\n"); ! free(softc->changer, M_DEVBUF); num_changers--; } devstat_remove_entry(softc->device_stats); destroy_dev(softc->dev); EVENTHANDLER_DEREGISTER(dev_clone, softc->clonetag); ! free(softc, M_DEVBUF); splx(s); } --- 528,540 ---- changer_links); xpt_print_path(periph->path); printf("removing changer entry\n"); ! free(softc->changer, M_CAM_CD); num_changers--; } devstat_remove_entry(softc->device_stats); destroy_dev(softc->dev); EVENTHANDLER_DEREGISTER(dev_clone, softc->clonetag); ! free(softc, M_CAM_CD); splx(s); } *************** *** 598,603 **** --- 602,644 ---- } } + static void + cdsysctlinit(void *context, int pending) + { + struct cam_periph *periph; + struct cd_softc *softc; + char tmpstr[80], tmpstr2[80]; + + periph = (struct cam_periph *)context; + softc = (struct cd_softc *)periph->softc; + + snprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number); + snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); + + mtx_lock(&Giant); + + sysctl_ctx_init(&softc->sysctl_ctx); + softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_kern_cam_cd), OID_AUTO, + tmpstr2, CTLFLAG_RD, 0, tmpstr); + + if (softc->sysctl_tree == NULL) { + printf("cdsysctlinit: unable to allocate sysctl tree\n"); + return; + } + + /* + * Now register the sysctl handler, so the user can the value on + * the fly. + */ + SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), + OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, + &softc->minimum_command_size, 0, cdcmdsizesysctl, "I", + "Minimum CDB size"); + + mtx_unlock(&Giant); + } + /* * We have a handler function for this so we can check the values when the * user sets them, instead of every time we look at them. *************** *** 642,648 **** struct ccb_setasync csa; struct ccb_pathinq cpi; struct ccb_getdev *cgd; ! char tmpstr[80], tmpstr2[80]; caddr_t match; cgd = (struct ccb_getdev *)arg; --- 683,689 ---- struct ccb_setasync csa; struct ccb_pathinq cpi; struct ccb_getdev *cgd; ! char tmpstr[80]; caddr_t match; cgd = (struct ccb_getdev *)arg; *************** *** 655,661 **** return(CAM_REQ_CMP_ERR); } ! softc = (struct cd_softc *)malloc(sizeof(*softc),M_DEVBUF,M_NOWAIT); if (softc == NULL) { printf("cdregister: Unable to probe new device. " --- 696,702 ---- return(CAM_REQ_CMP_ERR); } ! softc = (struct cd_softc *)malloc(sizeof(*softc),M_CAM_CD,M_NOWAIT); if (softc == NULL) { printf("cdregister: Unable to probe new device. " *************** *** 696,712 **** if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) softc->quirks |= CD_Q_10_BYTE_ONLY; ! snprintf(tmpstr, sizeof(tmpstr), "CAM CD unit %d", periph->unit_number); ! snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); ! sysctl_ctx_init(&softc->sysctl_ctx); ! softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, ! SYSCTL_STATIC_CHILDREN(_kern_cam_cd), OID_AUTO, ! tmpstr2, CTLFLAG_RD, 0, tmpstr); ! if (softc->sysctl_tree == NULL) { ! printf("cdregister: unable to allocate sysctl tree\n"); ! free(softc, M_DEVBUF); ! return (CAM_REQ_CMP_ERR); ! } /* The default is 6 byte commands, unless quirked otherwise */ if (softc->quirks & CD_Q_10_BYTE_ONLY) --- 737,743 ---- if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) softc->quirks |= CD_Q_10_BYTE_ONLY; ! TASK_INIT(&softc->sysctl_task, 0, cdsysctlinit, periph); /* The default is 6 byte commands, unless quirked otherwise */ if (softc->quirks & CD_Q_10_BYTE_ONLY) *************** *** 728,742 **** softc->minimum_command_size = 10; /* - * Now register the sysctl handler, so the user can the value on - * the fly. - */ - SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), - OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, - &softc->minimum_command_size, 0, cdcmdsizesysctl, "I", - "Minimum CDB size"); - - /* * We need to register the statistics structure for this device, * but we don't have the blocksize yet for it. So, we register * the structure and indicate that we don't have the blocksize --- 759,764 ---- *************** *** 889,895 **** */ else { nchanger = malloc(sizeof(struct cdchanger), ! M_DEVBUF, M_NOWAIT); if (nchanger == NULL) { softc->flags &= ~CD_FLAG_CHANGER; --- 911,917 ---- */ else { nchanger = malloc(sizeof(struct cdchanger), ! M_CAM_CD, M_NOWAIT); if (nchanger == NULL) { softc->flags &= ~CD_FLAG_CHANGER; *************** *** 1847,1852 **** --- 1869,1879 ---- xpt_announce_periph(periph, announce_buf); if (softc->flags & CD_FLAG_CHANGER) cdchangerschedule(softc); + /* + * Create our sysctl variables, now that we know + * we have successfully attached. + */ + taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task); } softc->state = CD_STATE_NORMAL; /* *************** *** 3716,3722 **** } if (length != 0) { ! databuf = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); } else databuf = NULL; --- 3743,3749 ---- } if (length != 0) { ! databuf = malloc(length, M_CAM_CD, M_WAITOK | M_ZERO); } else databuf = NULL; *************** *** 3823,3829 **** } bailout: if (databuf != NULL) ! free(databuf, M_DEVBUF); xpt_release_ccb(ccb); --- 3850,3856 ---- } bailout: if (databuf != NULL) ! free(databuf, M_CAM_CD); xpt_release_ccb(ccb); *************** *** 3849,3855 **** length = sizeof(*challenge_data); ! challenge_data = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); databuf = (u_int8_t *)challenge_data; --- 3876,3882 ---- length = sizeof(*challenge_data); ! challenge_data = malloc(length, M_CAM_CD, M_WAITOK | M_ZERO); databuf = (u_int8_t *)challenge_data; *************** *** 3866,3872 **** length = sizeof(*key2_data); ! key2_data = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); databuf = (u_int8_t *)key2_data; --- 3893,3899 ---- length = sizeof(*key2_data); ! key2_data = malloc(length, M_CAM_CD, M_WAITOK | M_ZERO); databuf = (u_int8_t *)key2_data; *************** *** 3883,3889 **** length = sizeof(*rpc_data); ! rpc_data = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); databuf = (u_int8_t *)rpc_data; --- 3910,3916 ---- length = sizeof(*rpc_data); ! rpc_data = malloc(length, M_CAM_CD, M_WAITOK | M_ZERO); databuf = (u_int8_t *)rpc_data; *************** *** 3916,3922 **** bailout: if (databuf != NULL) ! free(databuf, M_DEVBUF); xpt_release_ccb(ccb); --- 3943,3949 ---- bailout: if (databuf != NULL) ! free(databuf, M_CAM_CD); xpt_release_ccb(ccb); *************** *** 4025,4031 **** } if (length != 0) { ! databuf = malloc(length, M_DEVBUF, M_WAITOK | M_ZERO); } else databuf = NULL; --- 4052,4058 ---- } if (length != 0) { ! databuf = malloc(length, M_CAM_CD, M_WAITOK | M_ZERO); } else databuf = NULL; *************** *** 4119,4125 **** bailout: if (databuf != NULL) ! free(databuf, M_DEVBUF); xpt_release_ccb(ccb); --- 4146,4152 ---- bailout: if (databuf != NULL) ! free(databuf, M_CAM_CD); xpt_release_ccb(ccb); ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_da.c#59 - /usr/home/ken/perforce2/FreeBSD-ken/src/sys/cam/scsi/scsi_da.c ==== *** /tmp/tmp.285.1 Fri Aug 29 21:34:15 2003 --- /usr/home/ken/perforce2/FreeBSD-ken/src/sys/cam/scsi/scsi_da.c Fri Aug 29 21:22:33 2003 *************** *** 48,53 **** --- 48,54 ---- #include #include #include + #include #include *************** *** 133,138 **** --- 134,140 ---- struct disk_params params; struct disk disk; union ccb saved_ccb; + struct task sysctl_task; struct sysctl_ctx_list sysctl_ctx; struct sysctl_oid *sysctl_tree; }; *************** *** 388,393 **** --- 390,396 ---- static periph_init_t dainit; static void daasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg); + static void dasysctlinit(void *context, int pending); static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS); static periph_ctor_t daregister; static periph_dtor_t dacleanup; *************** *** 412,417 **** --- 415,422 ---- #define DA_DEFAULT_RETRY 4 #endif + MALLOC_DEFINE(M_CAM_DA, "dabuffers", "Buffers for da(4)"); + static int da_retry_count = DA_DEFAULT_RETRY; static int da_default_timeout = DA_DEFAULT_TIMEOUT; *************** *** 848,854 **** printf("can't remove sysctl context\n"); } disk_destroy(&softc->disk); ! free(softc, M_DEVBUF); } static void --- 853,859 ---- printf("can't remove sysctl context\n"); } disk_destroy(&softc->disk); ! free(softc, M_CAM_DA); } static void *************** *** 915,920 **** --- 920,960 ---- } } + static void + dasysctlinit(void *context, int pending) + { + struct cam_periph *periph; + struct da_softc *softc; + char tmpstr[80], tmpstr2[80]; + + periph = (struct cam_periph *)context; + softc = (struct da_softc *)periph; + + snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number); + snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); + + mtx_lock(&Giant); + sysctl_ctx_init(&softc->sysctl_ctx); + softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2, + CTLFLAG_RD, 0, tmpstr); + if (softc->sysctl_tree == NULL) { + printf("dasysctlinit: unable to allocate sysctl tree\n"); + return; + } + + /* + * Now register the sysctl handler, so the user can the value on + * the fly. + */ + SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), + OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, + &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I", + "Minimum CDB size"); + + mtx_unlock(&Giant); + } + static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS) { *************** *** 955,961 **** struct ccb_setasync csa; struct ccb_pathinq cpi; struct ccb_getdev *cgd; ! char tmpstr[80], tmpstr2[80]; caddr_t match; cgd = (struct ccb_getdev *)arg; --- 995,1001 ---- struct ccb_setasync csa; struct ccb_pathinq cpi; struct ccb_getdev *cgd; ! char tmpstr[80]; caddr_t match; cgd = (struct ccb_getdev *)arg; *************** *** 969,975 **** return(CAM_REQ_CMP_ERR); } ! softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF, M_NOWAIT|M_ZERO); if (softc == NULL) { --- 1009,1015 ---- return(CAM_REQ_CMP_ERR); } ! softc = (struct da_softc *)malloc(sizeof(*softc), M_CAM_DA, M_NOWAIT|M_ZERO); if (softc == NULL) { *************** *** 1008,1024 **** if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) softc->quirks |= DA_Q_NO_6_BYTE; ! snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number); ! snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); ! sysctl_ctx_init(&softc->sysctl_ctx); ! softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, ! SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2, ! CTLFLAG_RD, 0, tmpstr); ! if (softc->sysctl_tree == NULL) { ! printf("daregister: unable to allocate sysctl tree\n"); ! free(softc, M_DEVBUF); ! return (CAM_REQ_CMP_ERR); ! } /* * RBC devices don't have to support READ(6), only READ(10). --- 1048,1054 ---- if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) softc->quirks |= DA_Q_NO_6_BYTE; ! TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph); /* * RBC devices don't have to support READ(6), only READ(10). *************** *** 1050,1064 **** softc->minimum_cmd_size = 16; /* - * Now register the sysctl handler, so the user can the value on - * the fly. - */ - SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree), - OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, - &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I", - "Minimum CDB size"); - - /* * Block our timeout handler while we * add this softc to the dev list. */ --- 1080,1085 ---- *************** *** 1539,1546 **** } } free(csio->data_ptr, M_TEMP); ! if (announce_buf[0] != '\0') xpt_announce_periph(periph, announce_buf); softc->state = DA_STATE_NORMAL; /* * Since our peripheral may be invalidated by an error --- 1560,1573 ---- } } free(csio->data_ptr, M_TEMP); ! if (announce_buf[0] != '\0') { xpt_announce_periph(periph, announce_buf); + /* + * Create our sysctl variables, now that we know + * we have successfully attached. + */ + taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task); + } softc->state = DA_STATE_NORMAL; /* * Since our peripheral may be invalidated by an error ==== //depot/FreeBSD-ken/src/sys/kern/subr_taskqueue.c#12 - /usr/home/ken/perforce2/FreeBSD-ken/src/sys/kern/subr_taskqueue.c ==== *** /tmp/tmp.285.2 Fri Aug 29 21:34:15 2003 --- /usr/home/ken/perforce2/FreeBSD-ken/src/sys/kern/subr_taskqueue.c Fri Aug 29 18:47:53 2003 *************** *** 36,41 **** --- 36,43 ---- #include #include #include + #include + #include static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); *************** *** 44,49 **** --- 46,52 ---- static void *taskqueue_ih; static void *taskqueue_giant_ih; static struct mtx taskqueue_queues_mutex; + static struct proc *taskqueue_thread_proc; struct taskqueue { STAILQ_ENTRY(taskqueue) tq_link; *************** *** 233,238 **** --- 236,266 ---- taskqueue_run(taskqueue_swi_giant); } + static void + taskqueue_kthread(void *arg) + { + struct mtx kthread_mutex; + + bzero(&kthread_mutex, sizeof(kthread_mutex)); + + mtx_init(&kthread_mutex, "taskqueue kthread", NULL, MTX_DEF); + + mtx_lock(&kthread_mutex); + + for (;;) { + mtx_unlock(&kthread_mutex); + taskqueue_run(taskqueue_thread); + mtx_lock(&kthread_mutex); + msleep(&taskqueue_thread, &kthread_mutex, PWAIT, "tqthr", 0); + } + } + + static void + taskqueue_thread_enqueue(void *context) + { + wakeup(&taskqueue_thread); + } + TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0, swi_add(NULL, "task queue", taskqueue_swi_run, NULL, SWI_TQ, INTR_MPSAFE, &taskqueue_ih)); *************** *** 240,242 **** --- 268,274 ---- TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, 0, swi_add(NULL, "Giant task queue", taskqueue_swi_giant_run, NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih)); + + TASKQUEUE_DEFINE(thread, taskqueue_thread_enqueue, 0, + kthread_create(taskqueue_kthread, NULL, + &taskqueue_thread_proc, RFNOWAIT, 0, "taskqueue")); ==== //depot/FreeBSD-ken/src/sys/sys/taskqueue.h#4 - /usr/home/ken/perforce2/FreeBSD-ken/src/sys/sys/taskqueue.h ==== *** /tmp/tmp.285.3 Fri Aug 29 21:34:15 2003 --- /usr/home/ken/perforce2/FreeBSD-ken/src/sys/sys/taskqueue.h Wed Aug 27 22:06:06 2003 *************** *** 112,116 **** --- 112,117 ---- */ TASKQUEUE_DECLARE(swi_giant); TASKQUEUE_DECLARE(swi); + TASKQUEUE_DECLARE(thread); #endif /* !_SYS_TASKQUEUE_H_ */ --NzB8fVQJ5HfG6fxh--