1739 if (sctps->sctps_recvq_tq_list_cur_sz + 1 >
1740 sctps->sctps_recvq_tq_list_max_sz) {
1741 mutex_exit(&sctps->sctps_rq_tq_lock);
1742 cmn_err(CE_NOTE, "Cannot create more SCTP recvq taskq");
1743 return;
1744 }
1745
1746 (void) snprintf(tq_name, sizeof (tq_name), "sctp_rq_taskq_%d_%u",
1747 sctps->sctps_netstack->netstack_stackid,
1748 sctps->sctps_recvq_tq_list_cur_sz);
1749 tq = taskq_create(tq_name, thrs, minclsyspri, sctp_recvq_tq_task_min,
1750 max_tasks, TASKQ_PREPOPULATE);
1751 if (tq == NULL) {
1752 mutex_exit(&sctps->sctps_rq_tq_lock);
1753 cmn_err(CE_NOTE, "SCTP recvq taskq creation failed");
1754 return;
1755 }
1756 ASSERT(sctps->sctps_recvq_tq_list[
1757 sctps->sctps_recvq_tq_list_cur_sz] == NULL);
1758 sctps->sctps_recvq_tq_list[sctps->sctps_recvq_tq_list_cur_sz] = tq;
1759 atomic_add_32(&sctps->sctps_recvq_tq_list_cur_sz, 1);
1760 mutex_exit(&sctps->sctps_rq_tq_lock);
1761 }
1762
1763 #ifdef DEBUG
1764 uint32_t recvq_loop_cnt = 0;
1765 uint32_t recvq_call = 0;
1766 #endif
1767
1768 /*
1769 * Find the next recvq_tq to use. This routine will go thru all the
1770 * taskqs until it can dispatch a job for the sctp. If this fails,
1771 * it will create a new taskq and try it.
1772 */
1773 static boolean_t
1774 sctp_find_next_tq(sctp_t *sctp)
1775 {
1776 int next_tq, try;
1777 taskq_t *tq;
1778 sctp_stack_t *sctps = sctp->sctp_sctps;
1779
1780 /*
1781 * Note that since we don't hold a lock on sctp_rq_tq_lock for
1782 * performance reason, recvq_ta_list_cur_sz can be changed during
1783 * this loop. The problem this will create is that the loop may
1784 * not have tried all the recvq_tq. This should be OK.
1785 */
1786 next_tq = atomic_add_32_nv(&sctps->sctps_recvq_tq_list_cur, 1) %
1787 sctps->sctps_recvq_tq_list_cur_sz;
1788 for (try = 0; try < sctps->sctps_recvq_tq_list_cur_sz; try++) {
1789 tq = sctps->sctps_recvq_tq_list[next_tq];
1790 if (taskq_dispatch(tq, sctp_process_recvq, sctp,
1791 TQ_NOSLEEP) != NULL) {
1792 sctp->sctp_recvq_tq = tq;
1793 return (B_TRUE);
1794 }
1795 next_tq = (next_tq + 1) % sctps->sctps_recvq_tq_list_cur_sz;
1796 }
1797
1798 /*
1799 * Create one more taskq and try it. Note that sctp_inc_taskq()
1800 * may not have created another taskq if the number of recvq
1801 * taskqs is at the maximum. We are probably in a pretty bad
1802 * shape if this actually happens...
1803 */
1804 sctp_inc_taskq(sctps);
1805 tq = sctps->sctps_recvq_tq_list[sctps->sctps_recvq_tq_list_cur_sz - 1];
1806 if (taskq_dispatch(tq, sctp_process_recvq, sctp, TQ_NOSLEEP) != NULL) {
|
1739 if (sctps->sctps_recvq_tq_list_cur_sz + 1 >
1740 sctps->sctps_recvq_tq_list_max_sz) {
1741 mutex_exit(&sctps->sctps_rq_tq_lock);
1742 cmn_err(CE_NOTE, "Cannot create more SCTP recvq taskq");
1743 return;
1744 }
1745
1746 (void) snprintf(tq_name, sizeof (tq_name), "sctp_rq_taskq_%d_%u",
1747 sctps->sctps_netstack->netstack_stackid,
1748 sctps->sctps_recvq_tq_list_cur_sz);
1749 tq = taskq_create(tq_name, thrs, minclsyspri, sctp_recvq_tq_task_min,
1750 max_tasks, TASKQ_PREPOPULATE);
1751 if (tq == NULL) {
1752 mutex_exit(&sctps->sctps_rq_tq_lock);
1753 cmn_err(CE_NOTE, "SCTP recvq taskq creation failed");
1754 return;
1755 }
1756 ASSERT(sctps->sctps_recvq_tq_list[
1757 sctps->sctps_recvq_tq_list_cur_sz] == NULL);
1758 sctps->sctps_recvq_tq_list[sctps->sctps_recvq_tq_list_cur_sz] = tq;
1759 atomic_inc_32(&sctps->sctps_recvq_tq_list_cur_sz);
1760 mutex_exit(&sctps->sctps_rq_tq_lock);
1761 }
1762
1763 #ifdef DEBUG
1764 uint32_t recvq_loop_cnt = 0;
1765 uint32_t recvq_call = 0;
1766 #endif
1767
1768 /*
1769 * Find the next recvq_tq to use. This routine will go thru all the
1770 * taskqs until it can dispatch a job for the sctp. If this fails,
1771 * it will create a new taskq and try it.
1772 */
1773 static boolean_t
1774 sctp_find_next_tq(sctp_t *sctp)
1775 {
1776 int next_tq, try;
1777 taskq_t *tq;
1778 sctp_stack_t *sctps = sctp->sctp_sctps;
1779
1780 /*
1781 * Note that since we don't hold a lock on sctp_rq_tq_lock for
1782 * performance reason, recvq_ta_list_cur_sz can be changed during
1783 * this loop. The problem this will create is that the loop may
1784 * not have tried all the recvq_tq. This should be OK.
1785 */
1786 next_tq = atomic_inc_32_nv(&sctps->sctps_recvq_tq_list_cur) %
1787 sctps->sctps_recvq_tq_list_cur_sz;
1788 for (try = 0; try < sctps->sctps_recvq_tq_list_cur_sz; try++) {
1789 tq = sctps->sctps_recvq_tq_list[next_tq];
1790 if (taskq_dispatch(tq, sctp_process_recvq, sctp,
1791 TQ_NOSLEEP) != NULL) {
1792 sctp->sctp_recvq_tq = tq;
1793 return (B_TRUE);
1794 }
1795 next_tq = (next_tq + 1) % sctps->sctps_recvq_tq_list_cur_sz;
1796 }
1797
1798 /*
1799 * Create one more taskq and try it. Note that sctp_inc_taskq()
1800 * may not have created another taskq if the number of recvq
1801 * taskqs is at the maximum. We are probably in a pretty bad
1802 * shape if this actually happens...
1803 */
1804 sctp_inc_taskq(sctps);
1805 tq = sctps->sctps_recvq_tq_list[sctps->sctps_recvq_tq_list_cur_sz - 1];
1806 if (taskq_dispatch(tq, sctp_process_recvq, sctp, TQ_NOSLEEP) != NULL) {
|