diff options
author | Kenjiro Cho <kjc@cvs.openbsd.org> | 2004-01-14 08:42:24 +0000 |
---|---|---|
committer | Kenjiro Cho <kjc@cvs.openbsd.org> | 2004-01-14 08:42:24 +0000 |
commit | dc96390f9e05cb1309e6c9fa128c0a72b89f0738 (patch) | |
tree | c73d1ffaa59452686182ede44168305d8a72842a /sys/altq/altq_hfsc.c | |
parent | 804d7fbaf7680e96f53e137bf37667b65a05da9c (diff) |
eliminate the predefined special qids so that qids become simple
identifiers without embedded meanings.
this also allows us to make the semantics of the qid assignment in line
with the tag assignment in the next step.
ok, henning@
Diffstat (limited to 'sys/altq/altq_hfsc.c')
-rw-r--r-- | sys/altq/altq_hfsc.c | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/sys/altq/altq_hfsc.c b/sys/altq/altq_hfsc.c index 0a245d9b6ea..e78965cf9b2 100644 --- a/sys/altq/altq_hfsc.c +++ b/sys/altq/altq_hfsc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: altq_hfsc.c,v 1.20 2003/12/06 06:39:51 kjc Exp $ */ +/* $OpenBSD: altq_hfsc.c,v 1.21 2004/01/14 08:42:23 kjc Exp $ */ /* $KAME: altq_hfsc.c,v 1.17 2002/11/29 07:48:33 kjc Exp $ */ /* @@ -206,13 +206,15 @@ hfsc_add_queue(struct pf_altq *a) opts = &a->pq_u.hfsc_opts; - parent = NULL; - if (a->qid != HFSC_ROOTCLASS_HANDLE) - if ((parent = clh_to_clp(hif, a->parent_qid)) == NULL) - return (EINVAL); + if (a->parent_qid == HFSC_NULLCLASS_HANDLE && + hif->hif_rootclass == NULL) + parent = NULL; + else if ((parent = clh_to_clp(hif, a->parent_qid)) == NULL) + return (EINVAL); - if (a->qid >= HFSC_MAX_CLASSES || a->qid == 0) + if (a->qid == 0) return (EINVAL); + if (clh_to_clp(hif, a->qid) != NULL) return (EBUSY); @@ -333,7 +335,10 @@ hfsc_class_create(struct hfsc_if *hif, struct service_curve *rsc, struct hfsc_class *parent, int qlimit, int flags, int qid) { struct hfsc_class *cl, *p; - int s; + int i, s; + + if (hif->hif_classes >= HFSC_MAX_CLASSES) + return (NULL); #ifndef ALTQ_RED if (flags & HFCF_RED) { @@ -443,7 +448,27 @@ hfsc_class_create(struct hfsc_if *hif, struct service_curve *rsc, s = splimp(); hif->hif_classes++; - hif->hif_class_tbl[qid - 1] = cl; + + /* + * find a free slot in the class table. if the slot matching + * the lower bits of qid is free, use this slot. otherwise, + * use the first free slot. + */ + i = qid % HFSC_MAX_CLASSES; + if (hif->hif_class_tbl[i] == NULL) + hif->hif_class_tbl[i] = cl; + else { + for (i = 0; i < HFSC_MAX_CLASSES; i++) + if (hif->hif_class_tbl[i] == NULL) { + hif->hif_class_tbl[i] = cl; + break; + } + if (i == HFSC_MAX_CLASSES) { + splx(s); + goto err_ret; + } + } + if (flags & HFCF_DEFAULTCLASS) hif->hif_defaultclass = cl; @@ -492,7 +517,7 @@ hfsc_class_create(struct hfsc_if *hif, struct service_curve *rsc, static int hfsc_class_destroy(struct hfsc_class *cl) { - int s; + int i, s; if (cl == NULL) return (0); @@ -520,7 +545,13 @@ hfsc_class_destroy(struct hfsc_class *cl) } while ((p = p->cl_siblings) != NULL); ASSERT(p != NULL); } - cl->cl_hif->hif_class_tbl[cl->cl_handle - 1] = NULL; + + for (i = 0; i < HFSC_MAX_CLASSES; i++) + if (cl->cl_hif->hif_class_tbl[i] == cl) { + cl->cl_hif->hif_class_tbl[i] = NULL; + break; + } + cl->cl_hif->hif_classes--; splx(s); @@ -536,6 +567,12 @@ hfsc_class_destroy(struct hfsc_class *cl) red_destroy(cl->cl_red); #endif } + + if (cl == cl->cl_hif->hif_rootclass) + cl->cl_hif->hif_rootclass = NULL; + if (cl == cl->cl_hif->hif_defaultclass) + cl->cl_hif->hif_defaultclass = NULL; + if (cl->cl_usc != NULL) FREE(cl->cl_usc, M_DEVBUF); if (cl->cl_fsc != NULL) @@ -1586,12 +1623,21 @@ get_class_stats(struct hfsc_classstats *sp, struct hfsc_class *cl) static struct hfsc_class * clh_to_clp(struct hfsc_if *hif, u_int32_t chandle) { - u_int idx; + int i; + struct hfsc_class *cl; if (chandle == 0) return (NULL); - idx = chandle - 1; - if (idx >= HFSC_MAX_CLASSES) - return (NULL); - return (hif->hif_class_tbl[idx]); + /* + * first, try the slot corresponding to the lower bits of the handle. + * if it does not match, do the linear table search. + */ + i = chandle % HFSC_MAX_CLASSES; + if ((cl = hif->hif_class_tbl[i]) != NULL && cl->cl_handle == chandle) + return (cl); + for (i = 0; i < HFSC_MAX_CLASSES; i++) + if ((cl = hif->hif_class_tbl[i]) != NULL && + cl->cl_handle == chandle) + return (cl); + return (NULL); } |