From: kan.liang@intel.com
To: davem@davemloft.net, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org
Cc: jeffrey.t.kirsher@intel.com, mingo@redhat.com,
peterz@infradead.org, kuznet@ms2.inr.ac.ru, jmorris@namei.org,
yoshfuji@linux-ipv6.org, kaber@trash.net,
akpm@linux-foundation.org, keescook@chromium.org,
viro@zeniv.linux.org.uk, gorcunov@openvz.org,
john.stultz@linaro.org, aduyck@mirantis.com, ben@decadent.org.uk,
decot@googlers.com, fw@strlen.de, alexander.duyck@gmail.com,
daniel@iogearbox.net, tom@herbertland.com, rdunlap@infradead.org,
xiyou.wangcong@gmail.com, hannes@stressinduktion.org,
stephen@networkplumber.org, alexei.starovoitov@gmail.com,
jesse.brandeburg@intel.com, andi@firstfloor.org,
Kan Liang <kan.liang@intel.com>
Subject: [RFC V3 PATCH 15/26] net/netpolicy: implement netpolicy register
Date: Mon, 12 Sep 2016 07:55:48 -0700 [thread overview]
Message-ID: <1473692159-4017-16-git-send-email-kan.liang@intel.com> (raw)
In-Reply-To: <1473692159-4017-1-git-send-email-kan.liang@intel.com>
From: Kan Liang <kan.liang@intel.com>
The socket/task can only be benefited when it register itself with
specific policy. If it's the first time to register, a record will be
created and inserted into RCU hash table. The record includes ptr,
policy and object information. ptr is the socket/task's pointer which is
used as key to search the record in hash table. Object will be assigned
later.
This patch also introduces a new type NET_POLICY_INVALID, which
indicates that the task/socket are not registered.
np_hashtable_lock is introduced to protect the hash table.
Signed-off-by: Kan Liang <kan.liang@intel.com>
---
include/linux/netpolicy.h | 26 ++++++++
net/core/netpolicy.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+)
diff --git a/include/linux/netpolicy.h b/include/linux/netpolicy.h
index d6ba9f6..ee33978 100644
--- a/include/linux/netpolicy.h
+++ b/include/linux/netpolicy.h
@@ -17,6 +17,7 @@
#define __LINUX_NETPOLICY_H
enum netpolicy_name {
+ NET_POLICY_INVALID = -1,
NET_POLICY_NONE = 0,
NET_POLICY_CPU,
NET_POLICY_BULK,
@@ -80,12 +81,37 @@ struct netpolicy_info {
struct list_head obj_list[NETPOLICY_RXTX][NET_POLICY_MAX];
};
+struct netpolicy_instance {
+ struct net_device *dev;
+ enum netpolicy_name policy; /* required policy */
+ void *ptr; /* pointers */
+};
+
+/* check if policy is valid */
+static inline int is_net_policy_valid(enum netpolicy_name policy)
+{
+ return ((policy < NET_POLICY_MAX) && (policy > NET_POLICY_INVALID));
+}
+
#ifdef CONFIG_NETPOLICY
extern void update_netpolicy_sys_map(void);
+extern int netpolicy_register(struct netpolicy_instance *instance,
+ enum netpolicy_name policy);
+extern void netpolicy_unregister(struct netpolicy_instance *instance);
#else
static inline void update_netpolicy_sys_map(void)
{
}
+
+static inline int netpolicy_register(struct netpolicy_instance *instance,
+ enum netpolicy_name policy)
+{ return 0;
+}
+
+static inline void netpolicy_unregister(struct netpolicy_instance *instance)
+{
+}
+
#endif
#endif /*__LINUX_NETPOLICY_H*/
diff --git a/net/core/netpolicy.c b/net/core/netpolicy.c
index a739ac7..503ebd1 100644
--- a/net/core/netpolicy.c
+++ b/net/core/netpolicy.c
@@ -39,6 +39,19 @@
#include <linux/sort.h>
#include <linux/ctype.h>
#include <linux/cpu.h>
+#include <linux/hashtable.h>
+
+struct netpolicy_record {
+ struct hlist_node hash_node;
+ unsigned long ptr_id;
+ enum netpolicy_name policy;
+ struct net_device *dev;
+ struct netpolicy_object *rx_obj;
+ struct netpolicy_object *tx_obj;
+};
+
+static DEFINE_HASHTABLE(np_record_hash, 10);
+static DEFINE_SPINLOCK(np_hashtable_lock);
static int netpolicy_get_dev_info(struct net_device *dev,
struct netpolicy_dev_info *d_info)
@@ -226,6 +239,143 @@ static int netpolicy_enable(struct net_device *dev)
return 0;
}
+static struct netpolicy_record *netpolicy_record_search(unsigned long ptr_id)
+{
+ struct netpolicy_record *rec = NULL;
+
+ hash_for_each_possible_rcu(np_record_hash, rec, hash_node, ptr_id) {
+ if (rec->ptr_id == ptr_id)
+ break;
+ }
+
+ return rec;
+}
+
+static void put_queue(struct net_device *dev,
+ struct netpolicy_object *rx_obj,
+ struct netpolicy_object *tx_obj)
+{
+ if (!dev || !dev->netpolicy)
+ return;
+
+ if (rx_obj)
+ atomic_dec(&rx_obj->refcnt);
+ if (tx_obj)
+ atomic_dec(&tx_obj->refcnt);
+}
+
+static void netpolicy_record_clear_obj(void)
+{
+ struct netpolicy_record *rec;
+ int i;
+
+ spin_lock(&np_hashtable_lock);
+ hash_for_each_rcu(np_record_hash, i, rec, hash_node) {
+ put_queue(rec->dev, rec->rx_obj, rec->tx_obj);
+ rec->rx_obj = NULL;
+ rec->tx_obj = NULL;
+ }
+ spin_unlock(&np_hashtable_lock);
+}
+
+static void netpolicy_record_clear_dev_node(struct net_device *dev)
+{
+ struct netpolicy_record *rec;
+ int i;
+
+ spin_lock_bh(&np_hashtable_lock);
+ hash_for_each_rcu(np_record_hash, i, rec, hash_node) {
+ if (rec->dev == dev) {
+ hash_del_rcu(&rec->hash_node);
+ kfree(rec);
+ }
+ }
+ spin_unlock_bh(&np_hashtable_lock);
+}
+
+/**
+ * netpolicy_register() - Register per socket/task policy request
+ * @instance: NET policy per socket/task instance info
+ * @policy: request NET policy
+ *
+ * This function intends to register per socket/task policy request.
+ * If it's the first time to register, an record will be created and
+ * inserted into RCU hash table.
+ *
+ * The record includes ptr, policy and object info. ptr of the socket/task
+ * is the key to search the record in hash table. Object will be assigned
+ * until the first packet is received/transmitted.
+ *
+ * Return: 0 on success, others on failure
+ */
+int netpolicy_register(struct netpolicy_instance *instance,
+ enum netpolicy_name policy)
+{
+ unsigned long ptr_id = (uintptr_t)instance->ptr;
+ struct netpolicy_record *new, *old;
+
+ if (!is_net_policy_valid(policy)) {
+ instance->policy = NET_POLICY_INVALID;
+ return -EINVAL;
+ }
+
+ new = kzalloc(sizeof(*new), GFP_KERNEL);
+ if (!new) {
+ instance->policy = NET_POLICY_INVALID;
+ return -ENOMEM;
+ }
+
+ spin_lock_bh(&np_hashtable_lock);
+ /* Check it in mapping table */
+ old = netpolicy_record_search(ptr_id);
+ if (old) {
+ if (old->policy != policy) {
+ put_queue(old->dev, old->rx_obj, old->tx_obj);
+ old->rx_obj = NULL;
+ old->tx_obj = NULL;
+ old->policy = policy;
+ }
+ kfree(new);
+ } else {
+ new->ptr_id = ptr_id;
+ new->dev = instance->dev;
+ new->policy = policy;
+ hash_add_rcu(np_record_hash, &new->hash_node, ptr_id);
+ }
+ instance->policy = policy;
+ spin_unlock_bh(&np_hashtable_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(netpolicy_register);
+
+/**
+ * netpolicy_unregister() - Unregister per socket/task policy request
+ * @instance: NET policy per socket/task instance info
+ *
+ * This function intends to unregister policy request by del related record
+ * from hash table.
+ *
+ */
+void netpolicy_unregister(struct netpolicy_instance *instance)
+{
+ struct netpolicy_record *record;
+ unsigned long ptr_id = (uintptr_t)instance->ptr;
+
+ spin_lock_bh(&np_hashtable_lock);
+ /* del from hash table */
+ record = netpolicy_record_search(ptr_id);
+ if (record) {
+ hash_del_rcu(&record->hash_node);
+ /* The record cannot be share. It can be safely free. */
+ put_queue(record->dev, record->rx_obj, record->tx_obj);
+ kfree(record);
+ }
+ instance->policy = NET_POLICY_INVALID;
+ spin_unlock_bh(&np_hashtable_lock);
+}
+EXPORT_SYMBOL(netpolicy_unregister);
+
const char *policy_name[NET_POLICY_MAX] = {
"NONE",
"CPU",
@@ -833,6 +983,7 @@ static int netpolicy_notify(struct notifier_block *this,
break;
case NETDEV_GOING_DOWN:
uninit_netpolicy(dev);
+ netpolicy_record_clear_dev_node(dev);
#ifdef CONFIG_PROC_FS
proc_remove(dev->proc_dev);
dev->proc_dev = NULL;
@@ -871,6 +1022,8 @@ void update_netpolicy_sys_map(void)
dev->netpolicy->cur_policy = NET_POLICY_NONE;
+ /* clear mapping table */
+ netpolicy_record_clear_obj();
/* rebuild everything */
netpolicy_disable(dev);
netpolicy_enable(dev);
--
2.5.5
next prev parent reply other threads:[~2016-09-12 15:01 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-12 14:55 [RFC V3 PATCH 00/26] Kernel NET policy kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 01/26] net: introduce " kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 02/26] net/netpolicy: init " kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 03/26] net/netpolicy: get device queue irq information kan.liang
2016-09-12 16:48 ` Sergei Shtylyov
2016-09-13 12:23 ` Liang, Kan
2016-09-13 12:23 ` Liang, Kan
2016-09-13 13:14 ` Alexander Duyck
2016-09-13 13:14 ` Alexander Duyck
2016-09-13 13:22 ` Liang, Kan
2016-09-13 13:22 ` Liang, Kan
2016-09-12 14:55 ` [RFC V3 PATCH 04/26] net/netpolicy: get CPU information kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 05/26] net/netpolicy: create CPU and queue mapping kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 06/26] net/netpolicy: set and remove IRQ affinity kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 07/26] net/netpolicy: enable and disable NET policy kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 08/26] net/netpolicy: introduce NET policy object kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 09/26] net/netpolicy: set NET policy by policy name kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 10/26] net/netpolicy: add three new NET policies kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 11/26] net/netpolicy: add MIX policy kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 12/26] net/netpolicy: NET device hotplug kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 13/26] net/netpolicy: support CPU hotplug kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 14/26] net/netpolicy: handle channel changes kan.liang
2016-09-12 14:55 ` kan.liang [this message]
2016-09-12 14:55 ` [RFC V3 PATCH 16/26] net/netpolicy: introduce per socket netpolicy kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 17/26] net/netpolicy: introduce netpolicy_pick_queue kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 18/26] net/netpolicy: set tx queues according to policy kan.liang
2016-09-12 20:23 ` Tom Herbert
2016-09-12 20:23 ` Tom Herbert
2016-09-13 12:22 ` Liang, Kan
2016-09-13 12:22 ` Liang, Kan
2016-09-12 14:55 ` [RFC V3 PATCH 19/26] net/netpolicy: tc bpf extension to pick Tx queue kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 20/26] net/netpolicy: set Rx queues according to policy kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 21/26] net/netpolicy: introduce per task net policy kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 22/26] net/netpolicy: set per task policy by proc kan.liang
2016-09-12 17:01 ` Sergei Shtylyov
2016-09-12 14:55 ` [RFC V3 PATCH 23/26] net/netpolicy: fast path for finding the queues kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 24/26] net/netpolicy: optimize for queue pair kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 25/26] net/netpolicy: limit the total record number kan.liang
2016-09-12 14:55 ` [RFC V3 PATCH 26/26] Documentation/networking: Document NET policy kan.liang
2016-09-12 15:38 ` [RFC V3 PATCH 00/26] Kernel " Florian Westphal
2016-09-12 17:21 ` Cong Wang
2016-09-12 17:21 ` Cong Wang
2016-09-12 15:52 ` Eric Dumazet
2016-09-19 20:39 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1473692159-4017-16-git-send-email-kan.liang@intel.com \
--to=kan.liang@intel.com \
--cc=aduyck@mirantis.com \
--cc=akpm@linux-foundation.org \
--cc=alexander.duyck@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andi@firstfloor.org \
--cc=ben@decadent.org.uk \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=decot@googlers.com \
--cc=fw@strlen.de \
--cc=gorcunov@openvz.org \
--cc=hannes@stressinduktion.org \
--cc=jeffrey.t.kirsher@intel.com \
--cc=jesse.brandeburg@intel.com \
--cc=jmorris@namei.org \
--cc=john.stultz@linaro.org \
--cc=kaber@trash.net \
--cc=keescook@chromium.org \
--cc=kuznet@ms2.inr.ac.ru \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=peterz@infradead.org \
--cc=rdunlap@infradead.org \
--cc=stephen@networkplumber.org \
--cc=tom@herbertland.com \
--cc=viro@zeniv.linux.org.uk \
--cc=xiyou.wangcong@gmail.com \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.