int pktsched_setup(struct ifclassq *ifq, u_int32_t scheduler, u_int32_t sflags, classq_pkt_type_t ptype) { int error = 0; u_int32_t rflags; IFCQ_LOCK_ASSERT_HELD(ifq); VERIFY(machclk_freq != 0); /* Nothing to do unless the scheduler type changes */ if (ifq->ifcq_type == scheduler) return (0); /* * Remember the flags that need to be restored upon success, as * they may be cleared when we tear down existing scheduler. */ rflags = (ifq->ifcq_flags & IFCQF_ENABLED); if (ifq->ifcq_type != PKTSCHEDT_NONE) { (void) pktsched_teardown(ifq); /* Teardown should have succeeded */ VERIFY(ifq->ifcq_type == PKTSCHEDT_NONE); VERIFY(ifq->ifcq_disc == NULL); VERIFY(ifq->ifcq_enqueue == NULL); VERIFY(ifq->ifcq_dequeue == NULL); VERIFY(ifq->ifcq_dequeue_sc == NULL); VERIFY(ifq->ifcq_request == NULL); } switch (scheduler) { case PKTSCHEDT_TCQ: error = tcq_setup_ifclassq(ifq, sflags, ptype); break; case PKTSCHEDT_QFQ: error = qfq_setup_ifclassq(ifq, sflags, ptype); break; case PKTSCHEDT_FQ_CODEL: error = fq_if_setup_ifclassq(ifq, sflags, ptype); break; default: error = ENXIO; break; } if (error == 0) ifq->ifcq_flags |= rflags; return (error); }
int pktsched_setup(struct ifclassq *ifq, u_int32_t scheduler, u_int32_t sflags) { int error = 0; u_int32_t qflags = sflags; u_int32_t rflags; IFCQ_LOCK_ASSERT_HELD(ifq); VERIFY(machclk_freq != 0); /* Nothing to do unless the scheduler type changes */ if (ifq->ifcq_type == scheduler) return (0); qflags &= (PKTSCHEDF_QALG_RED | PKTSCHEDF_QALG_RIO | PKTSCHEDF_QALG_BLUE | PKTSCHEDF_QALG_SFB); /* These are mutually exclusive */ if (qflags != 0 && qflags != PKTSCHEDF_QALG_RED && qflags != PKTSCHEDF_QALG_RIO && qflags != PKTSCHEDF_QALG_BLUE && qflags != PKTSCHEDF_QALG_SFB) { panic("%s: RED|RIO|BLUE|SFB mutually exclusive\n", __func__); /* NOTREACHED */ } /* * Remember the flags that need to be restored upon success, as * they may be cleared when we tear down existing scheduler. */ rflags = (ifq->ifcq_flags & IFCQF_ENABLED); if (ifq->ifcq_type != PKTSCHEDT_NONE) { (void) pktsched_teardown(ifq); /* Teardown should have succeeded */ VERIFY(ifq->ifcq_type == PKTSCHEDT_NONE); VERIFY(ifq->ifcq_disc == NULL); VERIFY(ifq->ifcq_enqueue == NULL); VERIFY(ifq->ifcq_dequeue == NULL); VERIFY(ifq->ifcq_dequeue_sc == NULL); VERIFY(ifq->ifcq_request == NULL); } switch (scheduler) { #if PKTSCHED_PRIQ case PKTSCHEDT_PRIQ: error = priq_setup_ifclassq(ifq, sflags); break; #endif /* PKTSCHED_PRIQ */ case PKTSCHEDT_TCQ: error = tcq_setup_ifclassq(ifq, sflags); break; case PKTSCHEDT_QFQ: error = qfq_setup_ifclassq(ifq, sflags); break; case PKTSCHEDT_FQ_CODEL: error = fq_if_setup_ifclassq(ifq, sflags); break; default: error = ENXIO; break; } if (error == 0) ifq->ifcq_flags |= rflags; return (error); }