Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*


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) {