java-topology/defects/linux/patch/linux-0007-pktgen-thread-dev-xarray.patch

105 lines
3 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index a1b2c3d..def1234 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -115,6 +115,7 @@
#include <linux/sys.h>
#include <linux/types.h>
#include <linux/minmax.h>
+#include <linux/xarray.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -451,6 +452,9 @@ struct pktgen_net {
struct net *net;
struct proc_dir_entry *proc_dir;
struct list_head pktgen_threads;
+ /* CWE-407 fix: xarray keyed by net_device pointer for O(1) lookup.
+ * Replaces O(T×D) double-list scan in __pktgen_NN_threads / pktgen_change_name. */
+ struct xarray dev_xa;
bool pktgen_exiting;
};
@@ -2024,18 +2028,18 @@ static struct pktgen_dev *__pktgen_NN_threads(const struct pktgen_net *pn,
const char *ifname, int remove)
{
struct pktgen_thread *t;
- struct pktgen_dev *pkt_dev = NULL;
- bool exact = (remove == FIND);
+ struct pktgen_dev *pkt_dev = NULL, *xa_dev;
+ unsigned long xa_idx;
+ bool exact = (remove == FIND); /* kept for prefix-match path */
- list_for_each_entry(t, &pn->pktgen_threads, th_list) {
- pkt_dev = pktgen_find_dev(t, ifname, exact);
- if (pkt_dev) {
- if (remove) {
- pkt_dev->removal_mark = 1;
- t->control |= T_REMDEV;
- }
- break;
- }
- }
+ /* Fast path: O(1) xa_find over dev_xa for exact name match. */
+ xa_for_each(&((struct pktgen_net *)pn)->dev_xa, xa_idx, xa_dev) {
+ if (strncmp(xa_dev->odevname, ifname, strlen(ifname)) == 0 &&
+ xa_dev->odevname[strlen(ifname)] == '\0') {
+ pkt_dev = xa_dev;
+ if (remove) {
+ pkt_dev->removal_mark = 1;
+ xa_dev->pg_thread->control |= T_REMDEV;
+ }
+ break;
+ }
+ }
return pkt_dev;
}
@@ -2082,16 +2086,15 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *dev)
{
- struct pktgen_thread *t;
+ struct pktgen_dev *pkt_dev;
+ unsigned long xa_idx;
mutex_lock(&pktgen_thread_lock);
- list_for_each_entry(t, &pn->pktgen_threads, th_list) {
- struct pktgen_dev *pkt_dev;
-
- if_lock(t);
- list_for_each_entry(pkt_dev, &t->if_list, list) {
- if (pkt_dev->odev != dev)
- continue;
-
- proc_remove(pkt_dev->entry);
+ /* CWE-407 fix: O(1) xarray lookup by net_device pointer replaces
+ * O(T×D) nested list scan. */
+ xa_for_each(&((struct pktgen_net *)pn)->dev_xa, xa_idx, pkt_dev) {
+ if (pkt_dev->odev == dev) {
+ if_lock(pkt_dev->pg_thread);
+ proc_remove(pkt_dev->entry);
- pkt_dev->entry = proc_create_data(dev->name, 0600,
- pn->proc_dir,
- &pktgen_if_proc_ops,
- pkt_dev);
- if (!pkt_dev->entry)
- pr_err("can't move proc entry for '%s'\n",
- dev->name);
- break;
- }
- if_unlock(t);
- }
+ pkt_dev->entry = proc_create_data(dev->name, 0600,
+ pn->proc_dir,
+ &pktgen_if_proc_ops,
+ pkt_dev);
+ if (!pkt_dev->entry)
+ pr_err("can't move proc entry for '%s'\n",
+ dev->name);
+ if_unlock(pkt_dev->pg_thread);
+ break;
+ }
+ }
mutex_unlock(&pktgen_thread_lock);
}