diff mbox series

[net-next,3/3] mctp: Pass flow data & flow release events to drivers

Message ID 20211028061833.2390354-3-jk@codeconstruct.com.au (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series [net-next,1/3] mctp: Return new key from mctp_alloc_local_tag | expand

Checks

Context Check Description
netdev/cover_letter warning Series does not have a cover letter
netdev/fixes_present success Fixes tag not required for -next series
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers success CCed 5 of 5 maintainers
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/module_param success Was 0 now: 0
netdev/build_32bit fail Errors and warnings before: 52 this patch: 23
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success No Fixes tag
netdev/checkpatch warning WARNING: 'inital' may be misspelled - perhaps 'initial'? WARNING: Block comments use a trailing */ on a separate line WARNING: line length of 82 exceeds 80 columns
netdev/build_allmodconfig_warn fail Errors and warnings before: 12 this patch: 33
netdev/header_inline success No static functions without inline keyword in header files

Commit Message

Jeremy Kerr Oct. 28, 2021, 6:18 a.m. UTC
Now that we have an extension for MCTP data in skbs, populate the flow
when a key has been created for the packet, and add a device driver
operation to inform of flow destruction.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
 include/net/mctp.h       |  5 ++++
 include/net/mctpdevice.h | 14 ++++++++++
 net/mctp/device.c        | 51 +++++++++++++++++++++++++++++++++++++
 net/mctp/route.c         | 55 ++++++++++++++++++++++++++++++++++++++--
 4 files changed, 123 insertions(+), 2 deletions(-)

Comments

kernel test robot Oct. 28, 2021, 12:20 p.m. UTC | #1
Hi Jeremy,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Jeremy-Kerr/mctp-Return-new-key-from-mctp_alloc_local_tag/20211028-142024
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 5a48585d7ec1d0e1e83539d56846c1e513ef66ea
config: hexagon-randconfig-r041-20211027 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 5db7568a6a1fcb408eb8988abdaff2a225a8eb72)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/27aeac2b7b2395816e26dcd1c3f3a1da4ae89ffe
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Jeremy-Kerr/mctp-Return-new-key-from-mctp_alloc_local_tag/20211028-142024
        git checkout 27aeac2b7b2395816e26dcd1c3f3a1da4ae89ffe
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=hexagon 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from net/mctp/test/utils.c:7:
>> include/net/mctpdevice.h:36:14: warning: declaration of 'struct mctp_sk_key' will not be visible outside of this function [-Wvisibility]
                                                   struct mctp_sk_key *key);
                                                          ^
   include/net/mctpdevice.h:51:52: warning: declaration of 'struct mctp_sk_key' will not be visible outside of this function [-Wvisibility]
   void mctp_dev_set_key(struct mctp_dev *dev, struct mctp_sk_key *key);
                                                      ^
   include/net/mctpdevice.h:52:56: warning: declaration of 'struct mctp_sk_key' will not be visible outside of this function [-Wvisibility]
   void mctp_dev_release_key(struct mctp_dev *dev, struct mctp_sk_key *key);
                                                          ^
   3 warnings generated.


vim +36 include/net/mctpdevice.h

    33	
    34	struct mctp_netdev_ops {
    35		void			(*release_flow)(struct mctp_dev *dev,
  > 36							struct mctp_sk_key *key);
    37	};
    38	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/include/net/mctp.h b/include/net/mctp.h
index 7a5ba801703c..73d5db9164e1 100644
--- a/include/net/mctp.h
+++ b/include/net/mctp.h
@@ -152,6 +152,11 @@  struct mctp_sk_key {
 
 	/* expiry timeout; valid (above) cleared on expiry */
 	unsigned long	expiry;
+
+	/* free to use for device flow state tracking. Initialised to
+	 * zero on inital key creation*/
+	unsigned long	dev_flow_state;
+	struct mctp_dev	*dev;
 };
 
 struct mctp_skb_cb {
diff --git a/include/net/mctpdevice.h b/include/net/mctpdevice.h
index 3a439463f055..fb95f52ce1c9 100644
--- a/include/net/mctpdevice.h
+++ b/include/net/mctpdevice.h
@@ -21,6 +21,8 @@  struct mctp_dev {
 
 	unsigned int		net;
 
+	const struct mctp_netdev_ops *ops;
+
 	/* Only modified under RTNL. Reads have addrs_lock held */
 	u8			*addrs;
 	size_t			num_addrs;
@@ -29,12 +31,24 @@  struct mctp_dev {
 	struct rcu_head		rcu;
 };
 
+struct mctp_netdev_ops {
+	void			(*release_flow)(struct mctp_dev *dev,
+						struct mctp_sk_key *key);
+};
+
 #define MCTP_INITIAL_DEFAULT_NET	1
 
 struct mctp_dev *mctp_dev_get_rtnl(const struct net_device *dev);
 struct mctp_dev *__mctp_dev_get(const struct net_device *dev);
 
+int mctp_register_netdev(struct net_device *dev,
+			 const struct mctp_netdev_ops *ops);
+void mctp_unregister_netdev(struct net_device *dev);
+
 void mctp_dev_hold(struct mctp_dev *mdev);
 void mctp_dev_put(struct mctp_dev *mdev);
 
+void mctp_dev_set_key(struct mctp_dev *dev, struct mctp_sk_key *key);
+void mctp_dev_release_key(struct mctp_dev *dev, struct mctp_sk_key *key);
+
 #endif /* __NET_MCTPDEVICE_H */
diff --git a/net/mctp/device.c b/net/mctp/device.c
index 3827d62f52c9..8799ee77e7b7 100644
--- a/net/mctp/device.c
+++ b/net/mctp/device.c
@@ -260,6 +260,24 @@  void mctp_dev_put(struct mctp_dev *mdev)
 	}
 }
 
+void mctp_dev_release_key(struct mctp_dev *dev, struct mctp_sk_key *key)
+	__must_hold(&key->lock)
+{
+	if (!dev)
+		return;
+	if (dev->ops && dev->ops->release_flow)
+		dev->ops->release_flow(dev, key);
+	key->dev = NULL;
+	mctp_dev_put(dev);
+}
+
+void mctp_dev_set_key(struct mctp_dev *dev, struct mctp_sk_key *key)
+	__must_hold(&key->lock)
+{
+	mctp_dev_hold(dev);
+	key->dev = dev;
+}
+
 static struct mctp_dev *mctp_add_dev(struct net_device *dev)
 {
 	struct mctp_dev *mdev;
@@ -414,6 +432,39 @@  static int mctp_dev_notify(struct notifier_block *this, unsigned long event,
 	return NOTIFY_OK;
 }
 
+static int mctp_register_netdevice(struct net_device *dev,
+				   const struct mctp_netdev_ops *ops)
+{
+	struct mctp_dev *mdev;
+
+	mdev = mctp_add_dev(dev);
+	if (IS_ERR(mdev))
+		return PTR_ERR(mdev);
+
+	mdev->ops = ops;
+
+	return register_netdevice(dev);
+}
+
+int mctp_register_netdev(struct net_device *dev,
+			 const struct mctp_netdev_ops *ops)
+{
+	int rc;
+
+	rtnl_lock();
+	rc = mctp_register_netdevice(dev, ops);
+	rtnl_unlock();
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(mctp_register_netdev);
+
+void mctp_unregister_netdev(struct net_device *dev)
+{
+	unregister_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(mctp_unregister_netdev);
+
 static struct rtnl_af_ops mctp_af_ops = {
 	.family = AF_MCTP,
 	.fill_link_af = mctp_fill_link_af,
diff --git a/net/mctp/route.c b/net/mctp/route.c
index 82cc10a2fb0c..46c44823edb7 100644
--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -29,6 +29,8 @@ 
 static const unsigned int mctp_message_maxlen = 64 * 1024;
 static const unsigned long mctp_key_lifetime = 6 * CONFIG_HZ;
 
+static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev);
+
 /* route output callbacks */
 static int mctp_route_discard(struct mctp_route *route, struct sk_buff *skb)
 {
@@ -152,8 +154,19 @@  static struct mctp_sk_key *mctp_key_alloc(struct mctp_sock *msk,
 
 void mctp_key_unref(struct mctp_sk_key *key)
 {
-	if (refcount_dec_and_test(&key->refs))
-		kfree(key);
+	unsigned long flags;
+
+	if (!refcount_dec_and_test(&key->refs))
+		return;
+
+	/* even though no refs exist here, the lock allows us to stay
+	 * consistent with the locking requirement of mctp_dev_release_key
+	 */
+	spin_lock_irqsave(&key->lock, flags);
+	mctp_dev_release_key(key->dev, key);
+	spin_unlock_irqrestore(&key->lock, flags);
+
+	kfree(key);
 }
 
 static int mctp_key_add(struct mctp_sk_key *key, struct mctp_sock *msk)
@@ -204,6 +217,7 @@  static void __mctp_key_unlock_drop(struct mctp_sk_key *key, struct net *net,
 	key->reasm_head = NULL;
 	key->reasm_dead = true;
 	key->valid = false;
+	mctp_dev_release_key(key->dev, key);
 	spin_unlock_irqrestore(&key->lock, flags);
 
 	spin_lock_irqsave(&net->mctp.keys_lock, flags);
@@ -222,6 +236,40 @@  static void __mctp_key_unlock_drop(struct mctp_sk_key *key, struct net *net,
 
 }
 
+#ifdef CONFIG_MCTP_FLOWS
+static void mctp_skb_set_flow(struct sk_buff *skb, struct mctp_sk_key *key)
+{
+	struct mctp_flow *flow;
+
+	flow = skb_ext_add(skb, SKB_EXT_MCTP);
+	if (!flow)
+		return;
+
+	refcount_inc(&key->refs);
+	flow->key = key;
+}
+
+static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev)
+{
+	struct mctp_sk_key *key;
+	struct mctp_flow *flow;
+
+	flow = skb_ext_find(skb, SKB_EXT_MCTP);
+	if (!flow)
+		return;
+
+	key = flow->key;
+
+	if (WARN_ON(key->dev && key->dev != dev))
+		return;
+
+	mctp_dev_set_key(dev, key);
+}
+#else
+static void mctp_skb_set_flow(struct sk_buff *skb, struct mctp_sk_key *key) {}
+static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) {}
+#endif
+
 static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
 {
 	struct mctp_hdr *hdr = mctp_hdr(skb);
@@ -465,6 +513,8 @@  static int mctp_route_output(struct mctp_route *route, struct sk_buff *skb)
 		return -EHOSTUNREACH;
 	}
 
+	mctp_flow_prepare_output(skb, route->dev);
+
 	rc = dev_queue_xmit(skb);
 	if (rc)
 		rc = net_xmit_errno(rc);
@@ -803,6 +853,7 @@  int mctp_local_output(struct sock *sk, struct mctp_route *rt,
 			rc = PTR_ERR(key);
 			goto out_release;
 		}
+		mctp_skb_set_flow(skb, key);
 		/* done with the key in this scope */
 		mctp_key_unref(key);
 		tag |= MCTP_HDR_FLAG_TO;