634 mutex_exit(&stp->sd_qlock); \
635 queue_service(q); \
636 mutex_enter(&stp->sd_qlock); \
637 } \
638 ASSERT(stp->sd_nqueues == 0); \
639 ASSERT((stp->sd_qhead == NULL) && (stp->sd_qtail == NULL)); \
640 }
641
642 /*
643 * Constructor/destructor routines for the stream head cache
644 */
645 /* ARGSUSED */
646 static int
647 stream_head_constructor(void *buf, void *cdrarg, int kmflags)
648 {
649 stdata_t *stp = buf;
650
651 mutex_init(&stp->sd_lock, NULL, MUTEX_DEFAULT, NULL);
652 mutex_init(&stp->sd_reflock, NULL, MUTEX_DEFAULT, NULL);
653 mutex_init(&stp->sd_qlock, NULL, MUTEX_DEFAULT, NULL);
654 cv_init(&stp->sd_monitor, NULL, CV_DEFAULT, NULL);
655 cv_init(&stp->sd_iocmonitor, NULL, CV_DEFAULT, NULL);
656 cv_init(&stp->sd_refmonitor, NULL, CV_DEFAULT, NULL);
657 cv_init(&stp->sd_qcv, NULL, CV_DEFAULT, NULL);
658 cv_init(&stp->sd_zcopy_wait, NULL, CV_DEFAULT, NULL);
659 stp->sd_wrq = NULL;
660
661 return (0);
662 }
663
664 /* ARGSUSED */
665 static void
666 stream_head_destructor(void *buf, void *cdrarg)
667 {
668 stdata_t *stp = buf;
669
670 mutex_destroy(&stp->sd_lock);
671 mutex_destroy(&stp->sd_reflock);
672 mutex_destroy(&stp->sd_qlock);
673 cv_destroy(&stp->sd_monitor);
674 cv_destroy(&stp->sd_iocmonitor);
675 cv_destroy(&stp->sd_refmonitor);
676 cv_destroy(&stp->sd_qcv);
677 cv_destroy(&stp->sd_zcopy_wait);
678 }
679
680 /*
681 * Constructor/destructor routines for the queue cache
682 */
683 /* ARGSUSED */
684 static int
685 queue_constructor(void *buf, void *cdrarg, int kmflags)
686 {
687 queinfo_t *qip = buf;
688 queue_t *qp = &qip->qu_rqueue;
689 queue_t *wqp = &qip->qu_wqueue;
690 syncq_t *sq = &qip->qu_syncq;
691
692 qp->q_first = NULL;
693 qp->q_link = NULL;
694 qp->q_count = 0;
695 qp->q_mblkcnt = 0;
696 qp->q_sqhead = NULL;
697 qp->q_sqtail = NULL;
3289 stp->sd_struiowrq = NULL;
3290 stp->sd_struiordq = NULL;
3291 stp->sd_struiodnak = 0;
3292 stp->sd_struionak = NULL;
3293 stp->sd_t_audit_data = NULL;
3294 stp->sd_rput_opt = 0;
3295 stp->sd_wput_opt = 0;
3296 stp->sd_read_opt = 0;
3297 stp->sd_rprotofunc = strrput_proto;
3298 stp->sd_rmiscfunc = strrput_misc;
3299 stp->sd_rderrfunc = stp->sd_wrerrfunc = NULL;
3300 stp->sd_rputdatafunc = stp->sd_wputdatafunc = NULL;
3301 stp->sd_ciputctrl = NULL;
3302 stp->sd_nciputctrl = 0;
3303 stp->sd_qhead = NULL;
3304 stp->sd_qtail = NULL;
3305 stp->sd_servid = NULL;
3306 stp->sd_nqueues = 0;
3307 stp->sd_svcflags = 0;
3308 stp->sd_copyflag = 0;
3309
3310 return (stp);
3311 }
3312
3313 /*
3314 * Free a stream head.
3315 */
3316 void
3317 shfree(stdata_t *stp)
3318 {
3319 ASSERT(MUTEX_NOT_HELD(&stp->sd_lock));
3320
3321 stp->sd_wrq = NULL;
3322
3323 mutex_enter(&stp->sd_qlock);
3324 while (stp->sd_svcflags & STRS_SCHEDULED) {
3325 STRSTAT(strwaits);
3326 cv_wait(&stp->sd_qcv, &stp->sd_qlock);
3327 }
3328 mutex_exit(&stp->sd_qlock);
3329
3330 if (stp->sd_ciputctrl != NULL) {
3331 ASSERT(stp->sd_nciputctrl == n_ciputctrl - 1);
3332 SUMCHECK_CIPUTCTRL_COUNTS(stp->sd_ciputctrl,
3333 stp->sd_nciputctrl, 0);
3334 ASSERT(ciputctrl_cache != NULL);
3335 kmem_cache_free(ciputctrl_cache, stp->sd_ciputctrl);
3336 stp->sd_ciputctrl = NULL;
3337 stp->sd_nciputctrl = 0;
3338 }
3339 ASSERT(stp->sd_qhead == NULL);
3340 ASSERT(stp->sd_qtail == NULL);
3341 ASSERT(stp->sd_nqueues == 0);
3342 kmem_cache_free(stream_head_cache, stp);
3343 }
3344
3345 /*
3346 * Allocate a pair of queues and a syncq for the pair
3347 */
3348 queue_t *
3349 allocq(void)
3350 {
3351 queinfo_t *qip;
3352 queue_t *qp, *wqp;
3353 syncq_t *sq;
3354
3355 qip = kmem_cache_alloc(queue_cache, KM_SLEEP);
3356
3357 qp = &qip->qu_rqueue;
3358 wqp = &qip->qu_wqueue;
3359 sq = &qip->qu_syncq;
3360
3361 qp->q_last = NULL;
3362 qp->q_next = NULL;
|
634 mutex_exit(&stp->sd_qlock); \
635 queue_service(q); \
636 mutex_enter(&stp->sd_qlock); \
637 } \
638 ASSERT(stp->sd_nqueues == 0); \
639 ASSERT((stp->sd_qhead == NULL) && (stp->sd_qtail == NULL)); \
640 }
641
642 /*
643 * Constructor/destructor routines for the stream head cache
644 */
645 /* ARGSUSED */
646 static int
647 stream_head_constructor(void *buf, void *cdrarg, int kmflags)
648 {
649 stdata_t *stp = buf;
650
651 mutex_init(&stp->sd_lock, NULL, MUTEX_DEFAULT, NULL);
652 mutex_init(&stp->sd_reflock, NULL, MUTEX_DEFAULT, NULL);
653 mutex_init(&stp->sd_qlock, NULL, MUTEX_DEFAULT, NULL);
654 mutex_init(&stp->sd_pid_list_lock, NULL, MUTEX_DEFAULT, NULL);
655 cv_init(&stp->sd_monitor, NULL, CV_DEFAULT, NULL);
656 cv_init(&stp->sd_iocmonitor, NULL, CV_DEFAULT, NULL);
657 cv_init(&stp->sd_refmonitor, NULL, CV_DEFAULT, NULL);
658 cv_init(&stp->sd_qcv, NULL, CV_DEFAULT, NULL);
659 cv_init(&stp->sd_zcopy_wait, NULL, CV_DEFAULT, NULL);
660 list_create(&stp->sd_pid_list, sizeof (pid_node_t),
661 offsetof(pid_node_t, pn_ref_link));
662 stp->sd_wrq = NULL;
663
664 return (0);
665 }
666
667 /* ARGSUSED */
668 static void
669 stream_head_destructor(void *buf, void *cdrarg)
670 {
671 stdata_t *stp = buf;
672
673 mutex_destroy(&stp->sd_lock);
674 mutex_destroy(&stp->sd_reflock);
675 mutex_destroy(&stp->sd_qlock);
676 mutex_destroy(&stp->sd_pid_list_lock);
677 cv_destroy(&stp->sd_monitor);
678 cv_destroy(&stp->sd_iocmonitor);
679 cv_destroy(&stp->sd_refmonitor);
680 cv_destroy(&stp->sd_qcv);
681 cv_destroy(&stp->sd_zcopy_wait);
682 list_destroy(&stp->sd_pid_list);
683 }
684
685 /*
686 * Constructor/destructor routines for the queue cache
687 */
688 /* ARGSUSED */
689 static int
690 queue_constructor(void *buf, void *cdrarg, int kmflags)
691 {
692 queinfo_t *qip = buf;
693 queue_t *qp = &qip->qu_rqueue;
694 queue_t *wqp = &qip->qu_wqueue;
695 syncq_t *sq = &qip->qu_syncq;
696
697 qp->q_first = NULL;
698 qp->q_link = NULL;
699 qp->q_count = 0;
700 qp->q_mblkcnt = 0;
701 qp->q_sqhead = NULL;
702 qp->q_sqtail = NULL;
3294 stp->sd_struiowrq = NULL;
3295 stp->sd_struiordq = NULL;
3296 stp->sd_struiodnak = 0;
3297 stp->sd_struionak = NULL;
3298 stp->sd_t_audit_data = NULL;
3299 stp->sd_rput_opt = 0;
3300 stp->sd_wput_opt = 0;
3301 stp->sd_read_opt = 0;
3302 stp->sd_rprotofunc = strrput_proto;
3303 stp->sd_rmiscfunc = strrput_misc;
3304 stp->sd_rderrfunc = stp->sd_wrerrfunc = NULL;
3305 stp->sd_rputdatafunc = stp->sd_wputdatafunc = NULL;
3306 stp->sd_ciputctrl = NULL;
3307 stp->sd_nciputctrl = 0;
3308 stp->sd_qhead = NULL;
3309 stp->sd_qtail = NULL;
3310 stp->sd_servid = NULL;
3311 stp->sd_nqueues = 0;
3312 stp->sd_svcflags = 0;
3313 stp->sd_copyflag = 0;
3314 sh_insert_pid(stp, curproc);
3315
3316 return (stp);
3317 }
3318
3319 /*
3320 * Free a stream head.
3321 */
3322 void
3323 shfree(stdata_t *stp)
3324 {
3325 pid_node_t *pn;
3326
3327 ASSERT(MUTEX_NOT_HELD(&stp->sd_lock));
3328
3329 stp->sd_wrq = NULL;
3330
3331 mutex_enter(&stp->sd_qlock);
3332 while (stp->sd_svcflags & STRS_SCHEDULED) {
3333 STRSTAT(strwaits);
3334 cv_wait(&stp->sd_qcv, &stp->sd_qlock);
3335 }
3336 mutex_exit(&stp->sd_qlock);
3337
3338 if (stp->sd_ciputctrl != NULL) {
3339 ASSERT(stp->sd_nciputctrl == n_ciputctrl - 1);
3340 SUMCHECK_CIPUTCTRL_COUNTS(stp->sd_ciputctrl,
3341 stp->sd_nciputctrl, 0);
3342 ASSERT(ciputctrl_cache != NULL);
3343 kmem_cache_free(ciputctrl_cache, stp->sd_ciputctrl);
3344 stp->sd_ciputctrl = NULL;
3345 stp->sd_nciputctrl = 0;
3346 }
3347 ASSERT(stp->sd_qhead == NULL);
3348 ASSERT(stp->sd_qtail == NULL);
3349 ASSERT(stp->sd_nqueues == 0);
3350
3351 mutex_enter(&stp->sd_pid_list_lock);
3352 while ((pn = list_head(&stp->sd_pid_list)) != NULL) {
3353 list_remove(&stp->sd_pid_list, pn);
3354 kmem_free(pn, sizeof (*pn));
3355 }
3356 mutex_exit(&stp->sd_pid_list_lock);
3357
3358 kmem_cache_free(stream_head_cache, stp);
3359 }
3360
3361 void
3362 sh_insert_pid(struct stdata *stp, proc_t *p)
3363 {
3364 pid_node_t *pn;
3365
3366 mutex_enter(&stp->sd_pid_list_lock);
3367 pn = list_head(&stp->sd_pid_list);
3368 while (pn != NULL && pn->pn_pid != p->p_pidp->pid_id) {
3369 pn = list_next(&stp->sd_pid_list, pn);
3370 }
3371
3372 if (pn != NULL) {
3373 pn->pn_count++;
3374 } else {
3375 pn = kmem_zalloc(sizeof (*pn), KM_SLEEP);
3376 list_link_init(&pn->pn_ref_link);
3377 pn->pn_pid = p->p_pidp->pid_id;
3378 pn->pn_count = 1;
3379 list_insert_tail(&stp->sd_pid_list, pn);
3380 }
3381 mutex_exit(&stp->sd_pid_list_lock);
3382 }
3383 void
3384 sh_remove_pid(struct stdata *stp, proc_t *p)
3385 {
3386 pid_node_t *pn;
3387
3388 mutex_enter(&stp->sd_pid_list_lock);
3389 pn = list_head(&stp->sd_pid_list);
3390 while (pn != NULL && pn->pn_pid != p->p_pidp->pid_id) {
3391 pn = list_next(&stp->sd_pid_list, pn);
3392 }
3393
3394 if (pn != NULL) {
3395 if (pn->pn_count > 1)
3396 pn->pn_count--;
3397 else {
3398 list_remove(&stp->sd_pid_list, pn);
3399 kmem_free(pn, sizeof (*pn));
3400 }
3401 }
3402 mutex_exit(&stp->sd_pid_list_lock);
3403 }
3404
3405 conn_pid_node_list_hdr_t *
3406 sh_get_pid_list(struct stdata *stp)
3407 {
3408 int sz, n = 0;
3409 pid_node_t *pn;
3410 conn_pid_node_t *cpn;
3411 conn_pid_node_list_hdr_t *cph;
3412
3413 mutex_enter(&stp->sd_pid_list_lock);
3414
3415 n = list_size(&stp->sd_pid_list);
3416 sz = sizeof (conn_pid_node_list_hdr_t);
3417 sz += (n > 1)?((n - 1) * sizeof (conn_pid_node_t)):0;
3418
3419 cph = kmem_zalloc(sz, KM_SLEEP);
3420 cph->cph_magic = CONN_PID_NODE_LIST_HDR_MAGIC;
3421 cph->cph_contents = CONN_PID_NODE_LIST_HDR_XTI;
3422 cph->cph_pn_cnt = n;
3423 cph->cph_tot_size = sz;
3424 cph->cph_flags = 0;
3425 cph->cph_optional1 = 0;
3426 cph->cph_optional2 = 0;
3427
3428 if (cph->cph_pn_cnt > 0) {
3429 cpn = cph->cph_cpns;
3430 pn = list_head(&stp->sd_pid_list);
3431 while (pn != NULL) {
3432 PIDNODE2CONNPIDNODE(pn, cpn);
3433 pn = list_next(&stp->sd_pid_list, pn);
3434 cpn++;
3435 }
3436 }
3437
3438 mutex_exit(&stp->sd_pid_list_lock);
3439 return (cph);
3440 }
3441
3442 /*
3443 * Allocate a pair of queues and a syncq for the pair
3444 */
3445 queue_t *
3446 allocq(void)
3447 {
3448 queinfo_t *qip;
3449 queue_t *qp, *wqp;
3450 syncq_t *sq;
3451
3452 qip = kmem_cache_alloc(queue_cache, KM_SLEEP);
3453
3454 qp = &qip->qu_rqueue;
3455 wqp = &qip->qu_wqueue;
3456 sq = &qip->qu_syncq;
3457
3458 qp->q_last = NULL;
3459 qp->q_next = NULL;
|