diff options
author | Kenjiro Cho <kjc@cvs.openbsd.org> | 2002-05-17 07:19:45 +0000 |
---|---|---|
committer | Kenjiro Cho <kjc@cvs.openbsd.org> | 2002-05-17 07:19:45 +0000 |
commit | 483ceccac7d0851361ab279215972e0c29cb6223 (patch) | |
tree | 53ad3b3425e766c62201fa56482b9a1414d25c18 /sys | |
parent | 66237872139a844457e646fc63357f62a6b17281 (diff) |
sync with KAME.
- don't MALLOC() with M_WAITOK in the spl block.
move the allocation before splimp().
- when we reset vt of a class, reset the runtime service curve as well.
- don't use max() to compare 64 bit values.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/altq/altq_hfsc.c | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/sys/altq/altq_hfsc.c b/sys/altq/altq_hfsc.c index 75b9ad11f64..98d436bec99 100644 --- a/sys/altq/altq_hfsc.c +++ b/sys/altq/altq_hfsc.c @@ -1,5 +1,5 @@ -/* $OpenBSD: altq_hfsc.c,v 1.4 2002/03/14 01:26:26 millert Exp $ */ -/* $KAME: altq_hfsc.c,v 1.8 2000/12/14 08:12:46 thorpej Exp $ */ +/* $OpenBSD: altq_hfsc.c,v 1.5 2002/05/17 07:19:44 kjc Exp $ */ +/* $KAME: altq_hfsc.c,v 1.13 2002/05/16 11:02:58 kjc Exp $ */ /* * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved. @@ -70,11 +70,10 @@ static struct hfsc_class *hfsc_class_create(struct hfsc_if *, struct service_curve *, struct hfsc_class *, int, int); static int hfsc_class_destroy(struct hfsc_class *); static int hfsc_class_modify(struct hfsc_class *, - struct service_curve *, struct service_curve *); + struct service_curve *, struct service_curve *); static struct hfsc_class *hfsc_nextclass(struct hfsc_class *); -static int hfsc_enqueue(struct ifaltq *, struct mbuf *, - struct altq_pktattr *); +static int hfsc_enqueue(struct ifaltq *, struct mbuf *, struct altq_pktattr *); static struct mbuf *hfsc_dequeue(struct ifaltq *, int); static int hfsc_addq(struct hfsc_class *, struct mbuf *); @@ -112,11 +111,11 @@ static u_int dx2d(u_int64_t); static void sc2isc(struct service_curve *, struct internal_sc *); static void rtsc_init(struct runtime_sc *, struct internal_sc *, - u_int64_t, u_int64_t); + u_int64_t, u_int64_t); static u_int64_t rtsc_y2x(struct runtime_sc *, u_int64_t); static u_int64_t rtsc_x2y(struct runtime_sc *, u_int64_t); static void rtsc_min(struct runtime_sc *, struct internal_sc *, - u_int64_t, u_int64_t); + u_int64_t, u_int64_t); int hfscopen(dev_t, int, int, struct proc *); int hfscclose(dev_t, int, int, struct proc *); @@ -471,9 +470,24 @@ hfsc_class_modify(cl, rsc, fsc) struct hfsc_class *cl; struct service_curve *rsc, *fsc; { - struct internal_sc *tmp; + struct internal_sc *rsc_tmp, *fsc_tmp; int s; + if (rsc != NULL && (rsc->m1 != 0 || rsc->m2 != 0) && + cl->cl_rsc == NULL) { + MALLOC(rsc_tmp, struct internal_sc *, + sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); + if (rsc_tmp == NULL) + return (ENOMEM); + } + if (fsc != NULL && (fsc->m1 != 0 || fsc->m2 != 0) && + cl->cl_fsc == NULL) { + MALLOC(fsc_tmp, struct internal_sc *, + sizeof(struct internal_sc), M_DEVBUF, M_WAITOK); + if (fsc_tmp == NULL) + return (ENOMEM); + } + s = splimp(); if (!qempty(cl->cl_q)) hfsc_purgeq(cl); @@ -485,16 +499,8 @@ hfsc_class_modify(cl, rsc, fsc) cl->cl_rsc = NULL; } } else { - if (cl->cl_rsc == NULL) { - MALLOC(tmp, struct internal_sc *, - sizeof(struct internal_sc), - M_DEVBUF, M_WAITOK); - if (tmp == NULL) { - splx(s); - return (ENOMEM); - } - cl->cl_rsc = tmp; - } + if (cl->cl_rsc == NULL) + cl->cl_rsc = rsc_tmp; bzero(cl->cl_rsc, sizeof(struct internal_sc)); sc2isc(rsc, cl->cl_rsc); rtsc_init(&cl->cl_deadline, cl->cl_rsc, 0, 0); @@ -509,16 +515,8 @@ hfsc_class_modify(cl, rsc, fsc) cl->cl_fsc = NULL; } } else { - if (cl->cl_fsc == NULL) { - MALLOC(tmp, struct internal_sc *, - sizeof(struct internal_sc), - M_DEVBUF, M_WAITOK); - if (tmp == NULL) { - splx(s); - return (ENOMEM); - } - cl->cl_fsc = tmp; - } + if (cl->cl_fsc == NULL) + cl->cl_fsc = fsc_tmp; bzero(cl->cl_fsc, sizeof(struct internal_sc)); sc2isc(fsc, cl->cl_fsc); rtsc_init(&cl->cl_virtual, cl->cl_fsc, 0, 0); @@ -851,6 +849,16 @@ init_v(cl, len) /* already active */ break; + /* + * if parent became idle while this class was idle. + * reset vt and the runtime service curve. + */ + if (cl->cl_parent->cl_nactive == 0 || + cl->cl_parent->cl_vtperiod != cl->cl_parentperiod) { + cl->cl_vt = 0; + rtsc_init(&cl->cl_virtual, cl->cl_fsc, + 0, cl->cl_total); + } min_cl = actlist_first(cl->cl_parent->cl_actc); if (min_cl != NULL) { u_int64_t vt; @@ -862,17 +870,13 @@ init_v(cl, len) */ max_cl = actlist_last(cl->cl_parent->cl_actc); vt = (min_cl->cl_vt + max_cl->cl_vt) / 2; - if (cl->cl_parent->cl_vtperiod == cl->cl_parentperiod) - vt = max(cl->cl_vt, vt); - cl->cl_vt = vt; - } else { - /* no packet is backlogged. set vt to 0 */ - cl->cl_vt = 0; + if (cl->cl_parent->cl_vtperiod != cl->cl_parentperiod + || vt > cl->cl_vt) + cl->cl_vt = vt; } /* update the virtual curve */ - rtsc_min(&cl->cl_virtual, cl->cl_fsc, - cl->cl_vt, cl->cl_total); + rtsc_min(&cl->cl_virtual, cl->cl_fsc, cl->cl_vt, cl->cl_total); cl->cl_vtperiod++; /* increment vt period */ cl->cl_parentperiod = cl->cl_parent->cl_vtperiod; |