From d91a5a39e0974cdc227a869b0dceffd3701b56dd Mon Sep 17 00:00:00 2001 From: mikeb Date: Wed, 26 Apr 2017 15:50:59 +0000 Subject: [PATCH] Perform H-FSC root queue allocation in the kernel Since only leaf queues can have packets assigned to them, H-FSC requires the user specified root queue to have a parent. To simplify userland tools and the configuration interface, the kernel can be leveraged to set it up. ok henning --- sbin/pfctl/pfctl.c | 22 +++------------------- sbin/pfctl/pfctl_queue.c | 22 +++++++++------------- sys/net/hfsc.c | 27 +++++++++++++++++---------- sys/net/hfsc.h | 4 ++-- usr.bin/systat/pftop.c | 29 ++++++++++++----------------- 5 files changed, 43 insertions(+), 61 deletions(-) diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index 0ede855616d..9c39f37bb14 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.c,v 1.341 2017/04/23 07:41:25 jmc Exp $ */ +/* $OpenBSD: pfctl.c,v 1.342 2017/04/26 15:50:59 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1342,7 +1342,7 @@ pfctl_load_queue(struct pfctl *pf, u_int32_t ticket, struct pfctl_qsitem *qi) int pfctl_load_queues(struct pfctl *pf) { - struct pfctl_qsitem *qi, *tempqi, rqi; + struct pfctl_qsitem *qi, *tempqi; u_int32_t ticket; TAILQ_FOREACH(qi, &qspecs, entries) { @@ -1362,23 +1362,7 @@ pfctl_load_queues(struct pfctl *pf) TAILQ_FOREACH_SAFE(qi, &rootqs, entries, tempqi) { TAILQ_REMOVE(&rootqs, qi, entries); - - /* - * We must have a hidden root queue below the user- - * specified/visible root queue, due to the way the - * dequeueing works far down there... don't ask. - * the _ namespace is reserved for these. - */ - bzero(&rqi, sizeof(rqi)); - TAILQ_INIT(&rqi.children); - TAILQ_INSERT_TAIL(&rqi.children, qi, entries); - snprintf(rqi.qs.qname, PF_QNAME_SIZE, "_root_%s", - qi->qs.ifname); - strlcpy(rqi.qs.ifname, qi->qs.ifname, sizeof(rqi.qs.ifname)); - strlcpy(qi->qs.parent, rqi.qs.qname, sizeof(qi->qs.parent)); - - pfctl_load_queue(pf, ticket, &rqi); - + pfctl_load_queue(pf, ticket, qi); TAILQ_INSERT_HEAD(&rootqs, qi, entries); } diff --git a/sbin/pfctl/pfctl_queue.c b/sbin/pfctl/pfctl_queue.c index 3b5a47d114b..6e59fff7d22 100644 --- a/sbin/pfctl/pfctl_queue.c +++ b/sbin/pfctl/pfctl_queue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_queue.c,v 1.2 2014/04/19 14:22:32 henning Exp $ */ +/* $OpenBSD: pfctl_queue.c,v 1.3 2017/04/26 15:50:59 mikeb Exp $ */ /* * Copyright (c) 2003 - 2013 Henning Brauer @@ -139,18 +139,14 @@ pfctl_update_qstats(int dev) warn("DIOCGETQSTATS"); return (-1); } -// if (pqs.queue.qname[0] != '_') { -// if (pqs.queue.parent[0] && pqs.queue.parent[0] == '_') -// pqs.queue.parent[0] = 0; - if ((node = pfctl_find_queue_node(pqs.queue.qname, - pqs.queue.ifname)) != NULL) { - memcpy(&node->qstats.data, &qstats.data, - sizeof(qstats.data)); - update_avg(&node->qstats); - } else { - pfctl_insert_queue_node(pqs.queue, qstats); - } -// } + if ((node = pfctl_find_queue_node(pqs.queue.qname, + pqs.queue.ifname)) != NULL) { + memcpy(&node->qstats.data, &qstats.data, + sizeof(qstats.data)); + update_avg(&node->qstats); + } else { + pfctl_insert_queue_node(pqs.queue, qstats); + } } return (mnr); } diff --git a/sys/net/hfsc.c b/sys/net/hfsc.c index a71da8ac6a9..f28b6a5205c 100644 --- a/sys/net/hfsc.c +++ b/sys/net/hfsc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hfsc.c,v 1.36 2017/03/07 01:29:53 dlg Exp $ */ +/* $OpenBSD: hfsc.c,v 1.37 2017/04/26 15:50:59 mikeb Exp $ */ /* * Copyright (c) 2012-2013 Henning Brauer @@ -349,10 +349,12 @@ hfsc_pf_addqueue(struct hfsc_if *hif, struct pf_queuespec *q) KASSERT(hif != NULL); - if (q->parent_qid == HFSC_NULLCLASS_HANDLE && - hif->hif_rootclass == NULL) - parent = NULL; - else if ((parent = hfsc_clh2cph(hif, q->parent_qid)) == NULL) + if (q->parent_qid == 0 && hif->hif_rootclass == NULL) { + parent = hfsc_class_create(hif, NULL, NULL, NULL, NULL, + 0, 0, HFSC_ROOT_CLASS | q->qid); + if (parent == NULL) + return (EINVAL); + } else if ((parent = hfsc_clh2cph(hif, q->parent_qid)) == NULL) return (EINVAL); if (q->qid == 0) @@ -446,17 +448,22 @@ void hfsc_free(unsigned int idx, void *q) { struct hfsc_if *hif = q; - int i; + struct hfsc_class *cl; + int i, restart; KERNEL_ASSERT_LOCKED(); KASSERT(idx == 0); /* when hfsc is enabled we only use the first ifq */ timeout_del(&hif->hif_defer); - i = hif->hif_allocated; - do - hfsc_class_destroy(hif, hif->hif_class_tbl[--i]); - while (i > 0); + do { + restart = 0; + for (i = 0; i < hif->hif_allocated; i++) { + cl = hif->hif_class_tbl[i]; + if (hfsc_class_destroy(hif, cl) == EBUSY) + restart++; + } + } while (restart > 0); free(hif->hif_class_tbl, M_DEVBUF, hif->hif_allocated * sizeof(void *)); free(hif, M_DEVBUF, sizeof(*hif)); diff --git a/sys/net/hfsc.h b/sys/net/hfsc.h index 544d9df6259..88108f60d52 100644 --- a/sys/net/hfsc.h +++ b/sys/net/hfsc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: hfsc.h,v 1.11 2015/11/20 03:35:23 dlg Exp $ */ +/* $OpenBSD: hfsc.h,v 1.12 2017/04/26 15:50:59 mikeb Exp $ */ /* * Copyright (c) 2012-2013 Henning Brauer @@ -54,7 +54,7 @@ struct hfsc_sc { }; /* special class handles */ -#define HFSC_NULLCLASS_HANDLE 0 +#define HFSC_ROOT_CLASS 0x10000 #define HFSC_DEFAULT_CLASSES 64 #define HFSC_MAX_CLASSES 65535 diff --git a/usr.bin/systat/pftop.c b/usr.bin/systat/pftop.c index 1a193eb7da5..27120174a18 100644 --- a/usr.bin/systat/pftop.c +++ b/usr.bin/systat/pftop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pftop.c,v 1.35 2016/12/18 19:39:30 jasper Exp $ */ +/* $OpenBSD: pftop.c,v 1.36 2017/04/26 15:50:59 mikeb Exp $ */ /* * Copyright (c) 2001, 2007 Can Erkin Acar * Copyright (c) 2001 Daniel Hartmeier @@ -1544,22 +1544,17 @@ pfctl_update_qstats(void) error("DIOCGETQSTATS: %s", strerror(errno)); return (-1); } - if (pqs.queue.qname[0] != '_') { - if (pqs.queue.parent[0] && pqs.queue.parent[0] == '_') - pqs.queue.parent[0] = '\0'; - qstats.valid = 1; - gettimeofday(&qstats.timestamp, NULL); - if ((node = pfctl_find_queue_node(pqs.queue.qname, - pqs.queue.ifname)) != NULL) { - memcpy(&node->qstats_last, &node->qstats, - sizeof(struct queue_stats)); - memcpy(&node->qstats, &qstats, - sizeof(struct queue_stats)); - } else { - pfctl_insert_queue_node(pqs.queue, qstats); - } - } else - num_queues--; + qstats.valid = 1; + gettimeofday(&qstats.timestamp, NULL); + if ((node = pfctl_find_queue_node(pqs.queue.qname, + pqs.queue.ifname)) != NULL) { + memcpy(&node->qstats_last, &node->qstats, + sizeof(struct queue_stats)); + memcpy(&node->qstats, &qstats, + sizeof(struct queue_stats)); + } else { + pfctl_insert_queue_node(pqs.queue, qstats); + } } return (0); } -- 2.20.1