Skip to content

Commit

Permalink
patch: add patches for dpdk-stable-20.11.1
Browse files Browse the repository at this point in the history
Signed-off-by: ywc689 <[email protected]>
  • Loading branch information
ywc689 committed Jun 24, 2021
1 parent fa7bc4b commit 0e37d91
Show file tree
Hide file tree
Showing 4 changed files with 903 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
From fc25cda5bab943feac5455779fb6a6f00ee2a87d Mon Sep 17 00:00:00 2001
From: wencyu <[email protected]>
Date: Thu, 17 Jun 2021 20:39:55 +0800
Subject: [PATCH 1/4] kni: use netlink event for multicast (driver part)

Kni driver sends netlink event every time hw-multicast list updated by
kernel, the user kni app should capture the event and update multicast
to kni device.

Original way is using rte_kni_request to pass hw-multicast to user kni
module. That method works but finally memory corruption found, which is
not easy to address. That's why we use netlink event instead.

Signed-off-by: wencyu <[email protected]>
---
kernel/linux/kni/kni_net.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)

diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c
index 4b75208..cde565e 100644
--- a/kernel/linux/kni/kni_net.c
+++ b/kernel/linux/kni/kni_net.c
@@ -17,6 +17,8 @@
#include <linux/skbuff.h>
#include <linux/kthread.h>
#include <linux/delay.h>
+#include <linux/inetdevice.h>
+#include <net/netlink.h>

#include <rte_kni_common.h>
#include <kni_fifo.h>
@@ -128,6 +130,7 @@
ret_val = wait_event_interruptible_timeout(kni->wq,
kni_fifo_count(kni->resp_q), 3 * HZ);
if (signal_pending(current) || ret_val <= 0) {
+ pr_err("%s: wait_event_interruptible timeout\n", __func__);
ret = -ETIME;
goto fail;
}
@@ -657,6 +660,77 @@ void kni_net_release_fifo_phy(struct kni_dev *kni)
return (ret == 0) ? req.result : ret;
}

+static size_t
+kni_nlmsg_size(void)
+{
+ return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
+ + nla_total_size(4) /* IFA_ADDRESS */
+ + nla_total_size(4) /* IFA_LOCAL */
+ + nla_total_size(4) /* IFA_BROADCAST */
+ + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
+ + nla_total_size(4) /* IFA_FLAGS */
+ + nla_total_size(sizeof(struct ifa_cacheinfo)); /* IFA_CACHEINFO */
+}
+
+static void
+kni_net_set_rx_mode(struct net_device *dev)
+{
+ /*
+ * send event to notify user (DPDK KNI app) that multicast list changed,
+ * so that it can monitor multicast join/leave and set HW mc-addrs to
+ * kni dev accordinglly.
+ *
+ * this event is just an notification, we do not save any mc-addr here
+ * (so attribute space for us). user kni app should get maddrs after
+ * receive this notification.
+ *
+ * I was expecting kernel send some rtnl event for multicast join/leave,
+ * but it doesn't. By checking the call-chain of SIOCADDMULTI (ip maddr,
+ * manages only hardware multicast) and IP_ADD_MEMBERSHIP (ip_mc_join_group,
+ * used to for IPv4 multicast), no rtnl event sent.
+ *
+ * so as workaround, modify kni driver here to send RTM_NEWADDR.
+ * it may not suitalbe to use this event for mcast, but that should works.
+ * hope that won't affect other listener to this event.
+ *
+ * previous solution was using rte_kni_request to pass hw-maddr list to user.
+ * it "works" for times but finally memory corruption found, which is
+ * not easy to address (lock was added and reviewed). That's why we use
+ * netlink event instead.
+ */
+ struct sk_buff *skb;
+ struct net *net = dev_net(dev);
+ struct nlmsghdr *nlh;
+ struct ifaddrmsg *ifm;
+
+ skb = nlmsg_new(kni_nlmsg_size(), GFP_ATOMIC);
+ if (!skb)
+ return;
+
+ /* no other event for us ? */
+ nlh = nlmsg_put(skb, 0, 0, RTM_NEWADDR, sizeof(*ifm), 0);
+ if (!nlh) {
+ kfree_skb(skb);
+ return;
+ }
+
+ /* just send an notification so no other info */
+ ifm = nlmsg_data(nlh);
+ memset(ifm, 0, sizeof(*ifm));
+ ifm->ifa_family = AF_UNSPEC;
+ ifm->ifa_prefixlen = 0;
+ ifm->ifa_flags = 0;
+ ifm->ifa_scope = RT_SCOPE_NOWHERE;
+ ifm->ifa_index = 0;
+
+ nlmsg_end(skb, nlh);
+
+ /* other group ? */
+ pr_debug("%s: rx-mode/multicast-list changed\n", __func__);
+ rtnl_notify(skb, net, 0, RTNLGRP_NOTIFY, NULL, GFP_ATOMIC);
+ return;
+}
+
static void
kni_net_change_rx_flags(struct net_device *netdev, int flags)
{
@@ -757,6 +831,7 @@ void kni_net_release_fifo_phy(struct kni_dev *kni)
kni = netdev_priv(netdev);
ret = kni_net_process_request(kni, &req);

+ pr_info("%s request returns %d!\n", __func__, ret);
return (ret == 0 ? req.result : ret);
}

@@ -788,6 +863,7 @@ void kni_net_release_fifo_phy(struct kni_dev *kni)
.ndo_change_rx_flags = kni_net_change_rx_flags,
.ndo_start_xmit = kni_net_tx,
.ndo_change_mtu = kni_net_change_mtu,
+ .ndo_set_rx_mode = kni_net_set_rx_mode,
.ndo_tx_timeout = kni_net_tx_timeout,
.ndo_set_mac_address = kni_net_set_mac,
#ifdef HAVE_CHANGE_CARRIER_CB
--
1.8.3.1

Loading

0 comments on commit 0e37d91

Please sign in to comment.