* [PATCH 5/5] net/hyperv: Call netif_carrier_off() after register_netdev()
From: Ilya Shchepetkov @ 2012-08-14 10:28 UTC (permalink / raw)
To: K. Y. Srinivasan
Cc: Ilya Shchepetkov, Haiyang Zhang, David S. Miller, devel, netdev,
linux-kernel, ldv-project
In-Reply-To: <1344940135-17079-1-git-send-email-shchepetkov@ispras.ru>
For carrier detection to work properly when binding the driver with a
cable unplugged, netif_carrier_off() should be called after
register_netdev(), not before.
Calling netif_carrier_off() before register_netdev() was causing the
network interface to miss a linkwatch pending event leading to an
inconsistent state if the link is not up when interface is initialized.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Ilya Shchepetkov <shchepetkov@ispras.ru>
---
drivers/net/hyperv/netvsc_drv.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 8c5a1c4..5734ad0 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -416,9 +416,6 @@ static int netvsc_probe(struct hv_device *dev,
if (!net)
return -ENOMEM;
- /* Set initial state */
- netif_carrier_off(net);
-
net_device_ctx = netdev_priv(net);
net_device_ctx->device_ctx = dev;
hv_set_drvdata(dev, net);
@@ -441,6 +438,9 @@ static int netvsc_probe(struct hv_device *dev,
goto out;
}
+ /* Set initial state */
+ netif_carrier_off(net);
+
/* Notify the netvsc driver of the new device */
device_info.ring_size = ring_size;
ret = rndis_filter_device_add(dev, &device_info);
--
1.7.7
^ permalink raw reply related
* [Patch] net: allow calling rtmsg_ifinfo() in atomic
From: Cong Wang @ 2012-08-14 10:28 UTC (permalink / raw)
To: netdev
Cc: David S. Miller, John Fastabend, Greg Rose, Thomas Graf,
Eric Dumazet, Ben Hutchings, Cong Wang
(Against net tree.)
When running 'systemctl restart network.service', I got the following
warning:
[ 1123.199677]
[ 1123.310275] ===============================
[ 1123.442202] [ INFO: suspicious RCU usage. ]
[ 1123.558207] 3.6.0-rc1+ #109 Not tainted
[ 1123.665204] -------------------------------
[ 1123.768254] include/linux/rcupdate.h:430 Illegal context switch in RCU read-side critical section!
[ 1123.992320]
[ 1123.992320] other info that might help us debug this:
[ 1123.992320]
[ 1124.307382]
[ 1124.307382] rcu_scheduler_active = 1, debug_locks = 0
[ 1124.522220] 2 locks held by sysctl/5710:
[ 1124.648364] #0: (rtnl_mutex){+.+.+.}, at: [<ffffffff81768498>] rtnl_trylock+0x15/0x17
[ 1124.882211] #1: (rcu_read_lock){.+.+.+}, at: [<ffffffff81871df8>] rcu_lock_acquire+0x0/0x29
[ 1125.085209]
[ 1125.085209] stack backtrace:
[ 1125.332213] Pid: 5710, comm: sysctl Not tainted 3.6.0-rc1+ #109
[ 1125.441291] Call Trace:
[ 1125.545281] [<ffffffff8109d915>] lockdep_rcu_suspicious+0x109/0x112
[ 1125.667212] [<ffffffff8107c240>] rcu_preempt_sleep_check+0x45/0x47
[ 1125.781838] [<ffffffff8107c260>] __might_sleep+0x1e/0x19b
[ 1125.900306] [<ffffffff8113e4a2>] slab_pre_alloc_hook+0x2d/0x38
[ 1126.012217] [<ffffffff817508f4>] ? __alloc_skb+0x4c/0x1a2
[ 1126.115156] [<ffffffff811411ea>] kmem_cache_alloc_node+0x2c/0x1c2
[ 1126.260520] [<ffffffff8109cae1>] ? lock_is_held+0x8a/0x95
[ 1126.391261] [<ffffffff817508f4>] ? __alloc_skb+0x4c/0x1a2
[ 1126.515221] [<ffffffff817508f4>] __alloc_skb+0x4c/0x1a2
[ 1126.615272] [<ffffffff8176778b>] ? if_nlmsg_size+0x164/0x19b
[ 1126.741293] [<ffffffff8176718e>] nlmsg_new+0x14/0x16
[ 1126.863267] [<ffffffff8176994d>] rtmsg_ifinfo+0x3b/0xcd
[ 1126.982196] [<ffffffff8109cae1>] ? lock_is_held+0x8a/0x95
[ 1127.102201] [<ffffffff81769a0f>] rtnetlink_event+0x30/0x34
[ 1127.229490] [<ffffffff8198a241>] notifier_call_chain+0x96/0xcd
[ 1127.338260] [<ffffffff810760b3>] raw_notifier_call_chain+0x14/0x16
[ 1127.445223] [<ffffffff81757ac5>] call_netdevice_notifiers+0x4a/0x4f
[ 1127.560195] [<ffffffff81757ffb>] netdev_features_change+0x16/0x18
[ 1127.668273] [<ffffffff8175e0ee>] netdev_update_features+0x20/0x25
[ 1127.772188] [<ffffffff8175e125>] dev_disable_lro+0x32/0x6b
[ 1127.885174] [<ffffffff81872d26>] dev_forward_change+0x30/0xcb
[ 1128.013214] [<ffffffff818738c4>] addrconf_forward_change+0x85/0xc5
[ 1128.118328] [<ffffffff818739bc>] addrconf_sysctl_forward+0xb8/0x108
[ 1128.278964] [<ffffffff81873904>] ? addrconf_forward_change+0xc5/0xc5
[ 1128.383230] [<ffffffff811af269>] proc_sys_call_handler+0x8a/0xb8
[ 1128.475407] [<ffffffff811af2ab>] proc_sys_write+0x14/0x16
[ 1128.578263] [<ffffffff81152a9e>] vfs_write+0xaf/0xf6
[ 1128.674728] [<ffffffff81153edf>] ? fget_light+0x3a/0xa1
[ 1128.790492] [<ffffffff81152c99>] sys_write+0x4d/0x74
[ 1128.902165] [<ffffffff8112040e>] ? do_anonymous_page+0x162/0x1d6
[ 1129.017203] [<ffffffff8198dea9>] system_call_fastpath+0x16/0x1b
This is due to that we call rtmsg_ifinfo() with RCU read lock held,
and because rtmsg_ifinfo() may block, this is invalid.
This patch fixes it by allowing callees to specify GFP when
calling it. In this case, netdev_features_change() calls it
with GFP_ATOMIC.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: John Fastabend <john.r.fastabend@intel.com>
Cc: Greg Rose <gregory.v.rose@intel.com>
Cc: Thomas Graf <tgraf@suug.ch>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index db71c4a..8d5b0b0 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -621,7 +621,8 @@ extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
u32 id, long expires, u32 error);
-extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
+extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change,
+ gfp_t flags);
/* RTNL is used as a global lock for all changes to network configuration */
extern void rtnl_lock(void);
diff --git a/net/core/dev.c b/net/core/dev.c
index a39354e..8c44e4c 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1089,6 +1089,7 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
void netdev_features_change(struct net_device *dev)
{
call_netdevice_notifiers(NETDEV_FEAT_CHANGE, dev);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_ATOMIC);
}
EXPORT_SYMBOL(netdev_features_change);
@@ -1104,7 +1105,7 @@ void netdev_state_change(struct net_device *dev)
{
if (dev->flags & IFF_UP) {
call_netdevice_notifiers(NETDEV_CHANGE, dev);
- rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL);
}
}
EXPORT_SYMBOL(netdev_state_change);
@@ -1204,7 +1205,7 @@ int dev_open(struct net_device *dev)
if (ret < 0)
return ret;
- rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING, GFP_KERNEL);
call_netdevice_notifiers(NETDEV_UP, dev);
return ret;
@@ -1277,7 +1278,7 @@ static int dev_close_many(struct list_head *head)
__dev_close_many(head);
list_for_each_entry(dev, head, unreg_list) {
- rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING, GFP_KERNEL);
call_netdevice_notifiers(NETDEV_DOWN, dev);
}
@@ -4482,7 +4483,7 @@ int netdev_set_bond_master(struct net_device *slave, struct net_device *master)
else
slave->flags &= ~IFF_SLAVE;
- rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE);
+ rtmsg_ifinfo(RTM_NEWLINK, slave, IFF_SLAVE, GFP_KERNEL);
return 0;
}
EXPORT_SYMBOL(netdev_set_bond_master);
@@ -4776,7 +4777,7 @@ int dev_change_flags(struct net_device *dev, unsigned int flags)
changes = old_flags ^ dev->flags;
if (changes)
- rtmsg_ifinfo(RTM_NEWLINK, dev, changes);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, changes, GFP_KERNEL);
__dev_notify_flags(dev, old_flags);
return ret;
@@ -5289,7 +5290,7 @@ static void rollback_registered_many(struct list_head *head)
if (!dev->rtnl_link_ops ||
dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
- rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
+ rtmsg_ifinfo(RTM_DELLINK, dev, ~0U, GFP_KERNEL);
/*
* Flush the unicast and multicast chains
@@ -5643,7 +5644,7 @@ int register_netdevice(struct net_device *dev)
*/
if (!dev->rtnl_link_ops ||
dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
- rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL);
out:
return ret;
@@ -6227,7 +6228,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
- rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
+ rtmsg_ifinfo(RTM_DELLINK, dev, ~0U, GFP_KERNEL);
/*
* Flush the unicast and multicast chains
@@ -6260,7 +6261,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
* Prevent userspace races by waiting until the network
* device is fully setup before sending notifications.
*/
- rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL);
synchronize_net();
err = 0;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 2c5a0a0..ab214ce 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1631,7 +1631,7 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm)
}
dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
- rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U, GFP_KERNEL);
__dev_notify_flags(dev, old_flags);
return 0;
@@ -1962,14 +1962,14 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
-void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
+void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, gfp_t flags)
{
struct net *net = dev_net(dev);
struct sk_buff *skb;
int err = -ENOBUFS;
size_t if_info_size;
- skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL);
+ skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), flags);
if (skb == NULL)
goto errout;
@@ -1980,7 +1980,7 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
+ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, flags);
return;
errout:
if (err < 0)
@@ -2359,9 +2359,10 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
case NETDEV_UNREGISTER_BATCH:
case NETDEV_RELEASE:
case NETDEV_JOIN:
+ case NETDEV_FEAT_CHANGE:
break;
default:
- rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
+ rtmsg_ifinfo(RTM_NEWLINK, dev, 0, GFP_KERNEL);
break;
}
return NOTIFY_DONE;
^ permalink raw reply related
* [PATCH 4/5] sungem: Call netif_carrier_off() after register_netdev()
From: Ilya Shchepetkov @ 2012-08-14 10:28 UTC (permalink / raw)
To: David S. Miller; +Cc: Ilya Shchepetkov, netdev, linux-kernel, ldv-project
In-Reply-To: <1344940135-17079-1-git-send-email-shchepetkov@ispras.ru>
For carrier detection to work properly when binding the driver with a
cable unplugged, netif_carrier_off() should be called after
register_netdev(), not before.
Calling netif_carrier_off() before register_netdev() was causing the
network interface to miss a linkwatch pending event leading to an
inconsistent state if the link is not up when interface is initialized.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Ilya Shchepetkov <shchepetkov@ispras.ru>
---
drivers/net/ethernet/sun/sungem.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 9ae12d0..c57c9f6 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2909,7 +2909,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
gp->lstate = link_down;
gp->timer_ticks = 0;
- netif_carrier_off(dev);
gp->regs = ioremap(gemreg_base, gemreg_len);
if (!gp->regs) {
@@ -2988,6 +2987,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
goto err_out_free_consistent;
}
+ /* Turn off carrier */
+ netif_carrier_off(dev);
+
/* Undo the get_cell with appropriate locking (we could use
* ndo_init/uninit but that would be even more clumsy imho)
*/
--
1.7.7
^ permalink raw reply related
* Re: [PATCH 03/19] netfilter: nf_nat_sip: fix via header translation with multiple parameters
From: Patrick McHardy @ 2012-08-14 12:23 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev
In-Reply-To: <20120814002857.GC14483@1984>
On Tue, 14 Aug 2012, Pablo Neira Ayuso wrote:
> On Thu, Aug 09, 2012 at 10:08:47PM +0200, kaber@trash.net wrote:
>> From: Patrick McHardy <kaber@trash.net>
>>
>> Via-headers are parsed beginning at the first character after the Via-address.
>> When the address is translated first and its length decreases, the offset to
>> start parsing at is incorrect and header parameters might be missed.
>>
>> Update the offset after translating the Via-address to fix this.
>
> Applied, thanks Patrick.
Thanks Pablo. I'll submit the final IPv6-NAT patches once these three
patches have made it into net-next/nf-next.
^ permalink raw reply
* Re: [patch net-next 01/16] net: introduce upper device lists
From: Jiri Pirko @ 2012-08-14 12:24 UTC (permalink / raw)
To: Flavio Leitner
Cc: netdev, davem, edumazet, faisal.latif, roland, sean.hefty,
hal.rosenstock, fubar, andy, divy, jitendra.kalsaria, sony.chacko,
linux-driver, kaber, ursula.braun, blaschka, linux390, shemminger,
bhutchings, therbert, xiyou.wangcong, joe, gregory.v.rose,
john.r.fastabend, linux-rdma, linux-kernel, linux-s390, bridge
In-Reply-To: <20120813145217.38748c4f@obelix.rh>
Mon, Aug 13, 2012 at 07:52:17PM CEST, fbl@redhat.com wrote:
>On Mon, 13 Aug 2012 17:27:00 +0200
>Jiri Pirko <jiri@resnulli.us> wrote:
>
>> This lists are supposed to serve for storing pointers to all upper devices.
>> Eventually it will replace dev->master pointer which is used for
>> bonding, bridge, team but it cannot be used for vlan, macvlan where
>> there might be multiple "masters" present.
>>
>> New upper device list resolves this limitation. Also, the information
>> stored in lists is used for preventing looping setups like
>> "bond->somethingelse->samebond"
>>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>> ---
>> include/linux/netdevice.h | 14 +++
>> net/core/dev.c | 232 ++++++++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 244 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index a9db4f3..e7a07f8 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -1173,6 +1173,8 @@ struct net_device {
>> * which this device is member of.
>> */
>>
>> + struct list_head upper_dev_list; /* List of upper devices */
>> +
>> /* Interface address info used in eth_type_trans() */
>> unsigned char *dev_addr; /* hw address, (before bcast
>> because most packets are
>> @@ -2611,6 +2613,18 @@ extern int netdev_max_backlog;
>> extern int netdev_tstamp_prequeue;
>> extern int weight_p;
>> extern int bpf_jit_enable;
>> +
>> +extern bool netdev_has_upper_dev(struct net_device *dev,
>> + struct net_device *upper_dev);
>> +extern bool netdev_has_any_upper_dev(struct net_device *dev);
>> +extern struct net_device *netdev_unique_upper_dev_get(struct net_device *dev);
>> +extern struct net_device *netdev_unique_upper_dev_get_rcu(struct net_device *dev);
>> +extern int netdev_upper_dev_link(struct net_device *dev,
>> + struct net_device *upper_dev);
>> +extern int netdev_unique_upper_dev_link(struct net_device *dev,
>> + struct net_device *upper_dev);
>> +extern void netdev_upper_dev_unlink(struct net_device *dev,
>> + struct net_device *upper_dev);
>> extern int netdev_set_master(struct net_device *dev, struct net_device *master);
>> extern int netdev_set_bond_master(struct net_device *dev,
>> struct net_device *master);
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 1f06df8..68db1ac 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -4425,6 +4425,229 @@ static int __init dev_proc_init(void)
>> #endif /* CONFIG_PROC_FS */
>>
>>
>> +struct netdev_upper {
>> + struct net_device *dev;
>> + bool unique;
>
>unique is quite confusing here. I see that it is possible to have
>one unique and many non-unique linked in the list, so maybe rename
>to 'main_dev', 'master' or 'principal'...
>
>
>> + struct list_head list;
>> + struct rcu_head rcu;
>> +};
>> +
>> +static bool __netdev_has_upper_dev(struct net_device *dev,
>> + struct net_device *upper_dev,
>> + bool deep)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + list_for_each_entry(upper, &dev->upper_dev_list, list) {
>> + if (upper->dev == upper_dev)
>> + return true;
>> + if (deep && __netdev_has_upper_dev(upper->dev, upper_dev, deep))
>> + return true;
>> + }
>> + return false;
>> +}
>> +
>> +static struct netdev_upper *__netdev_find_upper(struct net_device *dev,
>> + struct net_device *upper_dev)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + list_for_each_entry(upper, &dev->upper_dev_list, list) {
>> + if (upper->dev == upper_dev)
>> + return upper;
>> + }
>> + return NULL;
>> +}
>> +
>> +/**
>> + * netdev_has_upper_dev - Check if device is linked to an upper device
>> + * @dev: device
>> + * @upper_dev: upper device to check
>> + *
>> + * Find out if a device is linked to specified upper device and return true
>> + * in case it is. The caller must hold the RTNL semaphore.
>> + */
>> +bool netdev_has_upper_dev(struct net_device *dev,
>> + struct net_device *upper_dev)
>> +{
>> + ASSERT_RTNL();
>> +
>> + return __netdev_has_upper_dev(dev, upper_dev, false);
>> +}
>> +EXPORT_SYMBOL(netdev_has_upper_dev);
>> +
>> +/**
>> + * netdev_has_any_upper_dev - Check if device is linked to some device
>> + * @dev: device
>> + *
>> + * Find out if a device is linked to an upper device and return true in case
>> + * it is. The caller must hold the RTNL semaphore.
>> + */
>> +bool netdev_has_any_upper_dev(struct net_device *dev)
>> +{
>> + ASSERT_RTNL();
>> +
>> + return !list_empty(&dev->upper_dev_list);
>> +}
>> +EXPORT_SYMBOL(netdev_has_any_upper_dev);
>> +
>> +/**
>> + * netdev_unique_upper_dev_get - Get unique upper device
>> + * @dev: device
>> + *
>> + * Find a unique upper device and return pointer to it or NULL in case
>> + * it's not there. The caller must hold the RTNL semaphore.
>> + */
>> +struct net_device *netdev_unique_upper_dev_get(struct net_device *dev)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + ASSERT_RTNL();
>> +
>> + if (list_empty(&dev->upper_dev_list))
>> + return NULL;
>> +
>> + upper = list_first_entry(&dev->upper_dev_list,
>> + struct netdev_upper, list);
>> + if (likely(upper->unique))
>> + return upper->dev;
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(netdev_unique_upper_dev_get);
>> +
>> +/**
>> + * netdev_unique_upper_dev_get_rcu - Get unique upper device
>> + * @dev: device
>> + *
>> + * Find a unique upper device and return pointer to it or NULL in case
>> + * it's not there. The caller must hold the RCU read lock.
>> + */
>> +struct net_device *netdev_unique_upper_dev_get_rcu(struct net_device *dev)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + upper = list_first_or_null_rcu(&dev->upper_dev_list,
>> + struct netdev_upper, list);
>> + if (likely(upper->unique))
>
>It will oopses here if 'upper' is NULL (i.e. no upper devices).
Fixed
>
>
>> + return upper->dev;
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL(netdev_unique_upper_dev_get_rcu);
>> +
>> +static int __netdev_upper_dev_link(struct net_device *dev,
>> + struct net_device *upper_dev, bool unique)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + ASSERT_RTNL();
>> +
>> + if (dev == upper_dev)
>> + return -EBUSY;
>> + /*
>> + * To prevent loops, check if dev is not upper device to upper_dev.
>> + */
>> + if (__netdev_has_upper_dev(upper_dev, dev, true))
>> + return -EBUSY;
>> +
>> + if (__netdev_find_upper(dev, upper_dev))
>> + return -EEXIST;
>
>__netdev_has_upper_dev() can go all the way up finding the device and
>the __netdev_find_upper() just check the first level.
I do not think this ordering is somewhat inportant.
>
>I think it would be better to use:
>__netdev_find_upper_dev(,,deep=true/false)
>__netdev_has_upper(,)
>
>thanks,
>fbl
>
>> + if (unique && netdev_unique_upper_dev_get(dev))
>> + return -EBUSY;
>> +
>> + upper = kmalloc(sizeof(*upper), GFP_KERNEL);
>> + if (!upper)
>> + return -ENOMEM;
>> +
>> + upper->dev = upper_dev;
>> + upper->unique = unique;
>> +
>> + /*
>> + * Ensure that unique upper link is always the first item in the list.
>> + */
>> + if (unique)
>> + list_add_rcu(&upper->list, &dev->upper_dev_list);
>> + else
>> + list_add_tail_rcu(&upper->list, &dev->upper_dev_list);
>> + dev_hold(upper_dev);
>> +
>> + return 0;
>> +}
>> +/**
>> + * netdev_upper_dev_link - Add a link to the upper device
>> + * @dev: device
>> + * @upper_dev: new upper device
>> + *
>> + * Adds a link to device which is upper to this one. The caller must hold
>> + * the RTNL semaphore. On a failure a negative errno code is returned.
>> + * On success the reference counts are adjusted and the function
>> + * returns zero.
>> + */
>> +int netdev_upper_dev_link(struct net_device *dev,
>> + struct net_device *upper_dev)
>> +{
>> + return __netdev_upper_dev_link(dev, upper_dev, false);
>> +}
>> +EXPORT_SYMBOL(netdev_upper_dev_link);
>> +
>> +/**
>> + * netdev_unique_upper_dev_link - Add a unique link to the upper device
>> + * @dev: device
>> + * @upper_dev: new upper device
>> + *
>> + * Adds a link to device which is upper to this one. In this case, only
>> + * one unique upper device can be linked, although other non-unique devices
>> + * might be linked as well. The caller must hold the RTNL semaphore.
>> + * On a failure a negative errno code is returned. On success the reference
>> + * counts are adjusted and the function returns zero.
>> + */
>> +int netdev_unique_upper_dev_link(struct net_device *dev,
>> + struct net_device *upper_dev)
>> +{
>> + return __netdev_upper_dev_link(dev, upper_dev, true);
>> +}
>> +EXPORT_SYMBOL(netdev_unique_upper_dev_link);
>> +
>> +/**
>> + * netdev_upper_free_rcu - Frees a upper device list item via the RCU pointer
>> + * @entry: the entry's RCU field
>> + *
>> + * This function is designed to be used as a callback to the call_rcu()
>> + * function so that the memory allocated to the netdev upper device list item
>> + * can be released safely.
>> + */
>> +static void netdev_upper_free_rcu(struct rcu_head *entry)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + upper = container_of(entry, struct netdev_upper, rcu);
>> + kfree(upper);
>> +}
>> +
>> +/**
>> + * netdev_upper_dev_unlink - Removes a link to upper device
>> + * @dev: device
>> + * @upper_dev: new upper device
>> + *
>> + * Removes a link to device which is upper to this one. The caller must hold
>> + * the RTNL semaphore.
>> + */
>> +void netdev_upper_dev_unlink(struct net_device *dev,
>> + struct net_device *upper_dev)
>> +{
>> + struct netdev_upper *upper;
>> +
>> + ASSERT_RTNL();
>> +
>> + upper = __netdev_find_upper(dev, upper_dev);
>> + if (!upper)
>> + return;
>> + list_del_rcu(&upper->list);
>> + dev_put(upper_dev);
>> + call_rcu(&upper->rcu, netdev_upper_free_rcu);
>> +}
>> +EXPORT_SYMBOL(netdev_upper_dev_unlink);
>> +
>> /**
>> * netdev_set_master - set up master pointer
>> * @slave: slave device
>> @@ -4438,19 +4661,23 @@ static int __init dev_proc_init(void)
>> int netdev_set_master(struct net_device *slave, struct net_device *master)
>> {
>> struct net_device *old = slave->master;
>> + int err;
>>
>> ASSERT_RTNL();
>>
>> if (master) {
>> if (old)
>> return -EBUSY;
>> - dev_hold(master);
>> + err = netdev_unique_upper_dev_link(slave, master);
>> + if (err)
>> + return err;
>> }
>>
>> slave->master = master;
>>
>> if (old)
>> - dev_put(old);
>> + netdev_upper_dev_unlink(slave, master);
>> +
>> return 0;
>> }
>> EXPORT_SYMBOL(netdev_set_master);
>> @@ -5999,6 +6226,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
>> INIT_LIST_HEAD(&dev->napi_list);
>> INIT_LIST_HEAD(&dev->unreg_list);
>> INIT_LIST_HEAD(&dev->link_watch_list);
>> + INIT_LIST_HEAD(&dev->upper_dev_list);
>> dev->priv_flags = IFF_XMIT_DST_RELEASE;
>> setup(dev);
>>
>
^ permalink raw reply
* RE: [PATCH 3/5] net/mlx4_en: Call netif_carrier_off() after register_netdev()
From: Sathya.Perla @ 2012-08-14 12:36 UTC (permalink / raw)
To: shchepetkov, yevgenyp
Cc: davem, amirv, ogerlitz, alexg, netdev, linux-kernel, ldv-project
In-Reply-To: <1344940135-17079-4-git-send-email-shchepetkov@ispras.ru>
>-----Original Message-----
>From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
>Behalf Of Ilya Shchepetkov
>
>For carrier detection to work properly when binding the driver with a
>cable unplugged, netif_carrier_off() should be called after
>register_netdev(), not before.
>
>Calling netif_carrier_off() before register_netdev() was causing the
>network interface to miss a linkwatch pending event leading to an
>inconsistent state if the link is not up when interface is initialized.
ndo_open() may be called as soon register_netdev() completes...
When netif_carrier_off() is called *after* register_netdev(), isn't there
a possibility of a ndo_open()->netif_carrier_on() call racing this call, causing
incorrect results?
^ permalink raw reply
* Re: [net PATCH v2 2/2] net: netprio: fd passed in SCM_RIGHTS datagram not set correctly
From: Neil Horman @ 2012-08-14 12:55 UTC (permalink / raw)
To: John Fastabend; +Cc: viro, netdev, davem, linux-kernel, joe
In-Reply-To: <20120814024326.6983.97403.stgit@jf-dev1-dcblab>
On Mon, Aug 13, 2012 at 07:43:27PM -0700, John Fastabend wrote:
> A socket fd passed in a SCM_RIGHTS datagram was not getting
> updated with the new tasks cgrp prioidx. This leaves IO on
> the socket tagged with the old tasks priority.
>
> To fix this add a check in the scm recvmsg path to update the
> sock cgrp prioidx with the new tasks value.
>
> Thanks to Al Viro for catching this.
>
> CC: Neil Horman <nhorman@tuxdriver.com>
> Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
>
> net/core/scm.c | 5 +++++
> 1 files changed, 5 insertions(+), 0 deletions(-)
>
> diff --git a/net/core/scm.c b/net/core/scm.c
> index 8f6ccfd..a14d9e2 100644
> --- a/net/core/scm.c
> +++ b/net/core/scm.c
> @@ -249,6 +249,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
> struct file **fp = scm->fp->fp;
> int __user *cmfptr;
> int err = 0, i;
> + __u32 prioidx = task_netprioidx(current);
>
> if (MSG_CMSG_COMPAT & msg->msg_flags) {
> scm_detach_fds_compat(msg, scm);
> @@ -265,6 +266,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
> for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax;
> i++, cmfptr++)
> {
> + struct socket *sock;
> int new_fd;
> err = security_file_receive(fp[i]);
> if (err)
> @@ -281,6 +283,9 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
> }
> /* Bump the usage count and install the file. */
> get_file(fp[i]);
> + sock = sock_from_file(fp[i], &err);
> + if (sock)
> + sock->sk->sk_cgrp_prioidx = prioidx;
nit: You can replace the prioidx variable above and this set with a call to
sock_update_netprioidx
Neil
^ permalink raw reply
* Re: [net PATCH v2 1/2] net: netprio: fix files lock and remove useless d_path bits
From: Neil Horman @ 2012-08-14 12:56 UTC (permalink / raw)
To: John Fastabend; +Cc: viro, netdev, davem, linux-kernel, joe
In-Reply-To: <20120814024320.6983.92222.stgit@jf-dev1-dcblab>
On Mon, Aug 13, 2012 at 07:43:21PM -0700, John Fastabend wrote:
> Add lock to prevent a race with a file closing and also remove
> useless and ugly sscanf code. The extra code was never needed
> and the case it supposedly protected against is in fact handled
> correctly by sock_from_file as pointed out by Al Viro.
>
> CC: Neil Horman <nhorman@tuxdriver.com>
> Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> ---
>
> net/core/netprio_cgroup.c | 22 ++++------------------
> 1 files changed, 4 insertions(+), 18 deletions(-)
>
> diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
> index ed0c043..f65dba3 100644
> --- a/net/core/netprio_cgroup.c
> +++ b/net/core/netprio_cgroup.c
> @@ -277,12 +277,6 @@ out_free_devname:
> void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
> {
> struct task_struct *p;
> - char *tmp = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL);
> -
> - if (!tmp) {
> - pr_warn("Unable to attach cgrp due to alloc failure!\n");
> - return;
> - }
>
> cgroup_taskset_for_each(p, cgrp, tset) {
> unsigned int fd;
> @@ -296,32 +290,24 @@ void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
> continue;
> }
>
> - rcu_read_lock();
> + spin_lock(&files->file_lock);
> fdt = files_fdtable(files);
> for (fd = 0; fd < fdt->max_fds; fd++) {
> - char *path;
> struct file *file;
> struct socket *sock;
> - unsigned long s;
> - int rv, err = 0;
> + int err;
>
> file = fcheck_files(files, fd);
> if (!file)
> continue;
>
> - path = d_path(&file->f_path, tmp, PAGE_SIZE);
> - rv = sscanf(path, "socket:[%lu]", &s);
> - if (rv <= 0)
> - continue;
> -
> sock = sock_from_file(file, &err);
> - if (!err)
> + if (sock)
> sock_update_netprioidx(sock->sk, p);
> }
> - rcu_read_unlock();
> + spin_unlock(&files->file_lock);
> task_unlock(p);
> }
> - kfree(tmp);
> }
>
> static struct cftype ss_files[] = {
>
This looks ok to me, but I've already shown my inability to review code that
interfaces with VFS. Al, what do you think?
Neil
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH 3/5] drivers/net/ethernet/freescale/fs_enet: fix error return code
From: Julia Lawall @ 2012-08-14 12:58 UTC (permalink / raw)
To: Pantelis Antoniou
Cc: kernel-janitors, Vitaly Bordug, linuxppc-dev, netdev,
linux-kernel
In-Reply-To: <1344949115-13266-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <Julia.Lawall@lip6.fr>
Convert a 0 error return code to a negative one, as returned elsewhere in the
function.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
identifier ret;
expression e,e1,e2,e3,e4,x;
@@
(
if (\(ret != 0\|ret < 0\) || ...) { ... return ...; }
|
ret = 0
)
... when != ret = e1
*x = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\|ioremap\|ioremap_nocache\|devm_ioremap\|devm_ioremap_nocache\)(...);
... when != x = e2
when != ret = e3
*if (x == NULL || ...)
{
... when != ret = e4
* return ret;
}
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c | 4 +++-
drivers/net/ethernet/freescale/fs_enet/mii-fec.c | 8 ++++++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
index 0f2d1a7..1514533 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
@@ -174,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
new_bus->phy_mask = ~0;
new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
- if (!new_bus->irq)
+ if (!new_bus->irq) {
+ ret = -ENOMEM;
goto out_unmap_regs;
+ }
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
index 55bb867..cdf702a 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
@@ -137,8 +137,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
fec->fecp = ioremap(res.start, resource_size(&res));
- if (!fec->fecp)
+ if (!fec->fecp) {
+ ret = -ENOMEM;
goto out_fec;
+ }
if (get_bus_freq) {
clock = get_bus_freq(ofdev->dev.of_node);
@@ -172,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev)
new_bus->phy_mask = ~0;
new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
- if (!new_bus->irq)
+ if (!new_bus->irq) {
+ ret = -ENOMEM;
goto out_unmap_regs;
+ }
new_bus->parent = &ofdev->dev;
dev_set_drvdata(&ofdev->dev, new_bus);
^ permalink raw reply related
* [PATCH 4/5] drivers/net/ethernet/mellanox/mlx4/mcg.c: fix error return code
From: Julia Lawall @ 2012-08-14 12:58 UTC (permalink / raw)
To: netdev; +Cc: kernel-janitors, linux-kernel
In-Reply-To: <1344949115-13266-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <Julia.Lawall@lip6.fr>
Convert a 0 error return code to a negative one, as returned elsewhere in the
function.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
identifier ret;
expression e,e1,e2,e3,e4,x;
@@
(
if (\(ret != 0\|ret < 0\) || ...) { ... return ...; }
|
ret = 0
)
... when != ret = e1
*x = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\|ioremap\|ioremap_nocache\|devm_ioremap\|devm_ioremap_nocache\)(...);
... when != x = e2
when != ret = e3
*if (x == NULL || ...)
{
... when != ret = e4
* return ret;
}
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
---
drivers/net/ethernet/mellanox/mlx4/mcg.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c
index 4ec3835..a018ea2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
@@ -432,8 +432,10 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port,
if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) {
/* Entry already exists, add to duplicates */
dqp = kmalloc(sizeof *dqp, GFP_KERNEL);
- if (!dqp)
+ if (!dqp) {
+ err = -ENOMEM;
goto out_mailbox;
+ }
dqp->qpn = qpn;
list_add_tail(&dqp->list, &entry->duplicates);
found = true;
^ permalink raw reply related
* [PATCH v3 0/6] cgroup cls & netprio 'cleanups'
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Al Viro, Andrew Morton,
Eric Dumazet, Gao feng, Glauber Costa, Jamal Hadi Salim,
John Fastabend, Kamezawa Hiroyuki, Li Zefan, Neil Horman,
Tejun Heo, Tim Chen
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Hi,
Sorry for the delay on updating this series. The usual
excuse apply here.
I saw that John is busy improving net_prio so I took the
liberty to port his changes to net_cls (#1-3). Patch #3 will
collide with John's unapplied patches. I am happy
to rebase this series if needed.
Patch #4 and #5 improve the readability with using
IS_MODULE/BUILTIN macros. This patches prepare the last
patch.
Patch #6 removes support for assigning subsystem IDs during
runtime. As it turns out this is not really needed. By doing
so we are able to free some unused memory.
The patches are against net-next.
cheers,
daniel
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Al Viro <viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: Tim Chen <tim.c.chen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Daniel Wagner (6):
cgroup: Move cls function definition to cls_cgroup.h
cgroup: net_cls rework update socket logic
cgroup: Update classid for fd pass in SCM_RIGHTS datagramm
cgroup: Use IS_MODULE/BUITLIN for net_cls
cgroup: Use IS_MODULE/BUITLIN for net_prio
cgroup: Assign subsystem IDs during compile time
include/linux/cgroup.h | 20 ++++++++++------
include/linux/cgroup_subsys.h | 24 +++++++++----------
include/net/cls_cgroup.h | 36 +++++++++++-----------------
include/net/netprio_cgroup.h | 38 +++++++----------------------
include/net/sock.h | 8 -------
kernel/cgroup.c | 31 +++++++-----------------
net/core/netprio_cgroup.c | 19 ++++++---------
net/core/scm.c | 7 +++++-
net/core/sock.c | 29 ++++++++++++----------
net/sched/cls_cgroup.c | 56 +++++++++++++++++++++++++++++++++----------
net/socket.c | 8 -------
11 files changed, 129 insertions(+), 147 deletions(-)
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply
* [PATCH v3 2/6] cgroup: net_cls rework update socket logic
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Andrew Morton, Eric Dumazet,
Gao feng, Glauber Costa, Jamal Hadi Salim, John Fastabend,
Kamezawa Hiroyuki, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1344949343-26090-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Update net_cls do do the same as net_prio does:
commit 406a3c638ce8b17d9704052c07955490f732c2b8
Author: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Fri Jul 20 10:39:25 2012 +0000
net: netprio_cgroup: rework update socket logic
Instead of updating the sk_cgrp_prioidx struct field on every send
this only updates the field when a task is moved via cgroup
infrastructure.
This allows sockets that may be used by a kernel worker thread
to be managed. For example in the iscsi case today a user can
put iscsid in a netprio cgroup and control traffic will be sent
with the correct sk_cgrp_prioidx value set but as soon as data
is sent the kernel worker thread isssues a send and sk_cgrp_prioidx
is updated with the kernel worker threads value which is the
default case.
It seems more correct to only update the field when the user
explicitly sets it via control group infrastructure. This allows
the users to manage sockets that may be used with other threads.
John already send an updated version for the attach function which
does not rely on the ugly scanf code, which I am using for this patch
here.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
Cc: Li Zefan <lizf-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 10 ++--------
net/core/netprio_cgroup.c | 2 +-
net/core/sock.c | 11 ++++++-----
net/sched/cls_cgroup.c | 38 ++++++++++++++++++++++++++++++++++++++
net/socket.c | 8 --------
5 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index 5f49b69..fc05f43 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,16 +24,13 @@ struct cgroup_cls_state
u32 classid;
};
-extern void sock_update_classid(struct sock *sk);
+extern void sock_update_classid(struct sock *sk, struct task_struct *task);
#ifdef CONFIG_NET_CLS_CGROUP
static inline u32 task_cls_classid(struct task_struct *p)
{
int classid;
- if (in_interrupt())
- return 0;
-
rcu_read_lock();
classid = container_of(task_subsys_state(p, net_cls_subsys_id),
struct cgroup_cls_state, css)->classid;
@@ -49,9 +46,6 @@ static inline u32 task_cls_classid(struct task_struct *p)
int id;
u32 classid = 0;
- if (in_interrupt())
- return 0;
-
rcu_read_lock();
id = rcu_dereference_index_check(net_cls_subsys_id,
rcu_read_lock_held());
@@ -64,7 +58,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
}
#endif
#else
-static inline void sock_update_classid(struct sock *sk)
+static inline void sock_update_classid(struct sock *sk, struct task_struct *task)
{
}
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index ed0c043..98478aa 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -274,7 +274,7 @@ out_free_devname:
return ret;
}
-void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
+static void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
{
struct task_struct *p;
char *tmp = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL);
diff --git a/net/core/sock.c b/net/core/sock.c
index 8f67ced..e08df6b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1223,13 +1223,14 @@ static void sk_prot_free(struct proto *prot, struct sock *sk)
}
#ifdef CONFIG_CGROUPS
-void sock_update_classid(struct sock *sk)
+void sock_update_classid(struct sock *sk, struct task_struct *task)
{
u32 classid;
- rcu_read_lock(); /* doing current task, which cannot vanish. */
- classid = task_cls_classid(current);
- rcu_read_unlock();
+ if (in_interrupt())
+ return;
+
+ classid = task_cls_classid(task);
if (classid && classid != sk->sk_classid)
sk->sk_classid = classid;
}
@@ -1269,7 +1270,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
sock_net_set(sk, get_net(net));
atomic_set(&sk->sk_wmem_alloc, 1);
- sock_update_classid(sk);
+ sock_update_classid(sk, current);
sock_update_netprioidx(sk, current);
}
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 7743ea8..3535771 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -17,6 +17,7 @@
#include <linux/skbuff.h>
#include <linux/cgroup.h>
#include <linux/rcupdate.h>
+#include <linux/fdtable.h>
#include <net/rtnetlink.h>
#include <net/pkt_cls.h>
#include <net/sock.h>
@@ -53,6 +54,42 @@ static void cgrp_destroy(struct cgroup *cgrp)
kfree(cgrp_cls_state(cgrp));
}
+static void cgrp_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
+{
+ struct task_struct *p;
+
+ cgroup_taskset_for_each(p, cgrp, tset) {
+ unsigned int fd;
+ struct fdtable *fdt;
+ struct files_struct *files;
+
+ task_lock(p);
+ files = p->files;
+ if (!files) {
+ task_unlock(p);
+ continue;
+ }
+
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ for (fd = 0; fd < fdt->max_fds; fd++) {
+ struct file *file;
+ struct socket *sock;
+ int err;
+
+ file = fcheck_files(files, fd);
+ if (!file)
+ continue;
+
+ sock = sock_from_file(file, &err);
+ if (sock)
+ sock_update_netprioidx(sock->sk, p);
+ }
+ spin_unlock(&files->file_lock);
+ task_unlock(p);
+ }
+}
+
static u64 read_classid(struct cgroup *cgrp, struct cftype *cft)
{
return cgrp_cls_state(cgrp)->classid;
@@ -77,6 +114,7 @@ struct cgroup_subsys net_cls_subsys = {
.name = "net_cls",
.create = cgrp_create,
.destroy = cgrp_destroy,
+ .attach = cgrp_attach,
#ifdef CONFIG_NET_CLS_CGROUP
.subsys_id = net_cls_subsys_id,
#endif
diff --git a/net/socket.c b/net/socket.c
index dfe5b66..f06c8c4 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -553,8 +553,6 @@ static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock,
{
struct sock_iocb *si = kiocb_to_siocb(iocb);
- sock_update_classid(sock->sk);
-
si->sock = sock;
si->scm = NULL;
si->msg = msg;
@@ -717,8 +715,6 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock,
{
struct sock_iocb *si = kiocb_to_siocb(iocb);
- sock_update_classid(sock->sk);
-
si->sock = sock;
si->scm = NULL;
si->msg = msg;
@@ -829,8 +825,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
if (unlikely(!sock->ops->splice_read))
return -EINVAL;
- sock_update_classid(sock->sk);
-
return sock->ops->splice_read(sock, ppos, pipe, len, flags);
}
@@ -3353,8 +3347,6 @@ EXPORT_SYMBOL(kernel_setsockopt);
int kernel_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags)
{
- sock_update_classid(sock->sk);
-
if (sock->ops->sendpage)
return sock->ops->sendpage(sock, page, offset, size, flags);
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v3 2/5] cgroup: rework update socket logic
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, Neil Horman, Li Zefan, John Fastabend, Gao feng,
Glauber Costa, Andrew Morton, Kamezawa Hiroyuki, Jamal Hadi Salim,
Eric Dumazet, David S. Miller
In-Reply-To: <1344949343-26090-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Update net_cls do do the same as net_prio does:
commit 406a3c638ce8b17d9704052c07955490f732c2b8
Author: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Date: Fri Jul 20 10:39:25 2012 +0000
net: netprio_cgroup: rework update socket logic
Instead of updating the sk_cgrp_prioidx struct field on every send
this only updates the field when a task is moved via cgroup
infrastructure.
This allows sockets that may be used by a kernel worker thread
to be managed. For example in the iscsi case today a user can
put iscsid in a netprio cgroup and control traffic will be sent
with the correct sk_cgrp_prioidx value set but as soon as data
is sent the kernel worker thread isssues a send and sk_cgrp_prioidx
is updated with the kernel worker threads value which is the
default case.
It seems more correct to only update the field when the user
explicitly sets it via control group infrastructure. This allows
the users to manage sockets that may be used with other threads.
John already send an updated version for the attach function which
does not rely on the ugly scanf code, which I am using for this patch
here.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Li Zefan <lizf-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
Cc: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
Cc: Eric Dumazet <edumazet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
include/net/cls_cgroup.h | 10 ++--------
net/core/netprio_cgroup.c | 2 +-
net/core/sock.c | 11 ++++++-----
net/sched/cls_cgroup.c | 38 ++++++++++++++++++++++++++++++++++++++
net/socket.c | 8 --------
5 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index 5f49b69..fc05f43 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,16 +24,13 @@ struct cgroup_cls_state
u32 classid;
};
-extern void sock_update_classid(struct sock *sk);
+extern void sock_update_classid(struct sock *sk, struct task_struct *task);
#ifdef CONFIG_NET_CLS_CGROUP
static inline u32 task_cls_classid(struct task_struct *p)
{
int classid;
- if (in_interrupt())
- return 0;
-
rcu_read_lock();
classid = container_of(task_subsys_state(p, net_cls_subsys_id),
struct cgroup_cls_state, css)->classid;
@@ -49,9 +46,6 @@ static inline u32 task_cls_classid(struct task_struct *p)
int id;
u32 classid = 0;
- if (in_interrupt())
- return 0;
-
rcu_read_lock();
id = rcu_dereference_index_check(net_cls_subsys_id,
rcu_read_lock_held());
@@ -64,7 +58,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
}
#endif
#else
-static inline void sock_update_classid(struct sock *sk)
+static inline void sock_update_classid(struct sock *sk, struct task_struct *task)
{
}
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index ed0c043..98478aa 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -274,7 +274,7 @@ out_free_devname:
return ret;
}
-void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
+static void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
{
struct task_struct *p;
char *tmp = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL);
diff --git a/net/core/sock.c b/net/core/sock.c
index 8f67ced..e08df6b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1223,13 +1223,14 @@ static void sk_prot_free(struct proto *prot, struct sock *sk)
}
#ifdef CONFIG_CGROUPS
-void sock_update_classid(struct sock *sk)
+void sock_update_classid(struct sock *sk, struct task_struct *task)
{
u32 classid;
- rcu_read_lock(); /* doing current task, which cannot vanish. */
- classid = task_cls_classid(current);
- rcu_read_unlock();
+ if (in_interrupt())
+ return;
+
+ classid = task_cls_classid(task);
if (classid && classid != sk->sk_classid)
sk->sk_classid = classid;
}
@@ -1269,7 +1270,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
sock_net_set(sk, get_net(net));
atomic_set(&sk->sk_wmem_alloc, 1);
- sock_update_classid(sk);
+ sock_update_classid(sk, current);
sock_update_netprioidx(sk, current);
}
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 7743ea8..3535771 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -17,6 +17,7 @@
#include <linux/skbuff.h>
#include <linux/cgroup.h>
#include <linux/rcupdate.h>
+#include <linux/fdtable.h>
#include <net/rtnetlink.h>
#include <net/pkt_cls.h>
#include <net/sock.h>
@@ -53,6 +54,42 @@ static void cgrp_destroy(struct cgroup *cgrp)
kfree(cgrp_cls_state(cgrp));
}
+static void cgrp_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
+{
+ struct task_struct *p;
+
+ cgroup_taskset_for_each(p, cgrp, tset) {
+ unsigned int fd;
+ struct fdtable *fdt;
+ struct files_struct *files;
+
+ task_lock(p);
+ files = p->files;
+ if (!files) {
+ task_unlock(p);
+ continue;
+ }
+
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ for (fd = 0; fd < fdt->max_fds; fd++) {
+ struct file *file;
+ struct socket *sock;
+ int err;
+
+ file = fcheck_files(files, fd);
+ if (!file)
+ continue;
+
+ sock = sock_from_file(file, &err);
+ if (sock)
+ sock_update_netprioidx(sock->sk, p);
+ }
+ spin_unlock(&files->file_lock);
+ task_unlock(p);
+ }
+}
+
static u64 read_classid(struct cgroup *cgrp, struct cftype *cft)
{
return cgrp_cls_state(cgrp)->classid;
@@ -77,6 +114,7 @@ struct cgroup_subsys net_cls_subsys = {
.name = "net_cls",
.create = cgrp_create,
.destroy = cgrp_destroy,
+ .attach = cgrp_attach,
#ifdef CONFIG_NET_CLS_CGROUP
.subsys_id = net_cls_subsys_id,
#endif
diff --git a/net/socket.c b/net/socket.c
index dfe5b66..f06c8c4 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -553,8 +553,6 @@ static inline int __sock_sendmsg_nosec(struct kiocb *iocb, struct socket *sock,
{
struct sock_iocb *si = kiocb_to_siocb(iocb);
- sock_update_classid(sock->sk);
-
si->sock = sock;
si->scm = NULL;
si->msg = msg;
@@ -717,8 +715,6 @@ static inline int __sock_recvmsg_nosec(struct kiocb *iocb, struct socket *sock,
{
struct sock_iocb *si = kiocb_to_siocb(iocb);
- sock_update_classid(sock->sk);
-
si->sock = sock;
si->scm = NULL;
si->msg = msg;
@@ -829,8 +825,6 @@ static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
if (unlikely(!sock->ops->splice_read))
return -EINVAL;
- sock_update_classid(sock->sk);
-
return sock->ops->splice_read(sock, ppos, pipe, len, flags);
}
@@ -3353,8 +3347,6 @@ EXPORT_SYMBOL(kernel_setsockopt);
int kernel_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags)
{
- sock_update_classid(sock->sk);
-
if (sock->ops->sendpage)
return sock->ops->sendpage(sock, page, offset, size, flags);
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v3 3/6] cgroup: Update classid for fd pass in SCM_RIGHTS datagramm
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA
Cc: Daniel Wagner, David S. Miller, Al Viro, David Howells,
Eric Dumazet, John Fastabend, Neil Horman, Tim Chen
In-Reply-To: <1344949343-26090-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
A socket fd passed in a SCM_RIGHTS datagram was not getting
updated with the new tasks cgrp classid. This leaves IO on
the socket tagged with the old tasks classid.
To fix this add a check in the scm recvmsg path to update the
sock cgrp classid with the new tasks value.
Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: Al Viro <viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
Cc: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Eric Dumazet <eric.dumazet-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
Cc: Tim Chen <tim.c.chen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
---
net/core/scm.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/core/scm.c b/net/core/scm.c
index 8f6ccfd..221080f 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -35,7 +35,7 @@
#include <net/sock.h>
#include <net/compat.h>
#include <net/scm.h>
-
+#include <net/cls_cgroup.h>
/*
* Only allow a user to send credentials, that they could set with
@@ -249,6 +249,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
struct file **fp = scm->fp->fp;
int __user *cmfptr;
int err = 0, i;
+ __u32 classid = task_cls_classid(current);
if (MSG_CMSG_COMPAT & msg->msg_flags) {
scm_detach_fds_compat(msg, scm);
@@ -265,6 +266,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax;
i++, cmfptr++)
{
+ struct socket *sock;
int new_fd;
err = security_file_receive(fp[i]);
if (err)
@@ -282,6 +284,9 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
/* Bump the usage count and install the file. */
get_file(fp[i]);
fd_install(new_fd, fp[i]);
+ sock = sock_from_file(fp[i], &err);
+ if (sock)
+ sock->sk->sk_classid = classid;
}
if (i > 0)
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v3 1/6] cgroup: Move cls function definition to cls_cgroup.h
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev, cgroups; +Cc: Daniel Wagner, David S. Miller, Li Zefan, Tejun Heo
In-Reply-To: <1344949343-26090-1-git-send-email-wagi@monom.org>
From: Daniel Wagner <daniel.wagner@bmw-carit.de>
sock_update_classid() is used by net/socket.c which includes
cls_cgroup.h directly.
Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: cgroups@vger.kernel.org
Cc: netdev@vger.kernel.org
---
include/net/cls_cgroup.h | 7 +++++++
include/net/sock.h | 8 --------
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index a4dc5b0..5f49b69 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -24,6 +24,8 @@ struct cgroup_cls_state
u32 classid;
};
+extern void sock_update_classid(struct sock *sk);
+
#ifdef CONFIG_NET_CLS_CGROUP
static inline u32 task_cls_classid(struct task_struct *p)
{
@@ -62,9 +64,14 @@ static inline u32 task_cls_classid(struct task_struct *p)
}
#endif
#else
+static inline void sock_update_classid(struct sock *sk)
+{
+}
+
static inline u32 task_cls_classid(struct task_struct *p)
{
return 0;
}
#endif
+
#endif /* _NET_CLS_CGROUP_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 72132ae..160a680 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1486,14 +1486,6 @@ extern void *sock_kmalloc(struct sock *sk, int size,
extern void sock_kfree_s(struct sock *sk, void *mem, int size);
extern void sk_send_sigurg(struct sock *sk);
-#ifdef CONFIG_CGROUPS
-extern void sock_update_classid(struct sock *sk);
-#else
-static inline void sock_update_classid(struct sock *sk)
-{
-}
-#endif
-
/*
* Functions to fill in entries in struct proto_ops when a protocol
* does not implement a particular function.
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v3 4/6] cgroup: Use IS_MODULE/BUITLIN for net_cls
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev, cgroups
Cc: Daniel Wagner, David S. Miller, Eric Dumazet, Glauber Costa,
Kamezawa Hiroyuki, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1344949343-26090-1-git-send-email-wagi@monom.org>
From: Daniel Wagner <daniel.wagner@bmw-carit.de>
Instead of using #ifdef variation for building the net_cls
in the different configuration use explicit IS_MODULE and
IS_BUILTIN macros.
This allows to reorder in readable way the cls_cgroup.h header file
so that the common definition of the struct is first followed
by the two different version for task_cls_classid().
Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: netdev@vger.kernel.org
Cc: cgroups@vger.kernel.org
---
include/net/cls_cgroup.h | 32 ++++++++++++++++++++------------
net/core/sock.c | 4 +++-
net/sched/cls_cgroup.c | 6 +++---
3 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index fc05f43..865ea49 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -17,7 +17,8 @@
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
-#ifdef CONFIG_CGROUPS
+#if IS_ENABLED(CONFIG_NET_CLS_CGROUP)
+
struct cgroup_cls_state
{
struct cgroup_subsys_state css;
@@ -26,7 +27,21 @@ struct cgroup_cls_state
extern void sock_update_classid(struct sock *sk, struct task_struct *task);
-#ifdef CONFIG_NET_CLS_CGROUP
+#else
+
+static inline void sock_update_classid(struct sock *sk, struct task_struct *task)
+{
+}
+
+static inline u32 task_cls_classid(struct task_struct *p)
+{
+ return 0;
+}
+
+#endif
+
+#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
+
static inline u32 task_cls_classid(struct task_struct *p)
{
int classid;
@@ -38,7 +53,9 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#else
+
+#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
+
extern int net_cls_subsys_id;
static inline u32 task_cls_classid(struct task_struct *p)
@@ -56,16 +73,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#endif
-#else
-static inline void sock_update_classid(struct sock *sk, struct task_struct *task)
-{
-}
-static inline u32 task_cls_classid(struct task_struct *p)
-{
- return 0;
-}
#endif
#endif /* _NET_CLS_CGROUP_H */
diff --git a/net/core/sock.c b/net/core/sock.c
index e08df6b..d2d920e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -327,7 +327,7 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
EXPORT_SYMBOL(__sk_backlog_rcv);
#if defined(CONFIG_CGROUPS)
-#if !defined(CONFIG_NET_CLS_CGROUP)
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
int net_cls_subsys_id = -1;
EXPORT_SYMBOL_GPL(net_cls_subsys_id);
#endif
@@ -1223,6 +1223,7 @@ static void sk_prot_free(struct proto *prot, struct sock *sk)
}
#ifdef CONFIG_CGROUPS
+#if IS_ENABLED(CONFIG_NET_CLS_CGROUP)
void sock_update_classid(struct sock *sk, struct task_struct *task)
{
u32 classid;
@@ -1235,6 +1236,7 @@ void sock_update_classid(struct sock *sk, struct task_struct *task)
sk->sk_classid = classid;
}
EXPORT_SYMBOL(sock_update_classid);
+#endif
void sock_update_netprioidx(struct sock *sk, struct task_struct *task)
{
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 3535771..9ffe9b5 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -115,7 +115,7 @@ struct cgroup_subsys net_cls_subsys = {
.create = cgrp_create,
.destroy = cgrp_destroy,
.attach = cgrp_attach,
-#ifdef CONFIG_NET_CLS_CGROUP
+#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
.subsys_id = net_cls_subsys_id,
#endif
.base_cftypes = ss_files,
@@ -321,7 +321,7 @@ static int __init init_cgroup_cls(void)
if (ret)
goto out;
-#ifndef CONFIG_NET_CLS_CGROUP
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
/* We can't use rcu_assign_pointer because this is an int. */
smp_wmb();
net_cls_subsys_id = net_cls_subsys.subsys_id;
@@ -339,7 +339,7 @@ static void __exit exit_cgroup_cls(void)
{
unregister_tcf_proto_ops(&cls_cgroup_ops);
-#ifndef CONFIG_NET_CLS_CGROUP
+#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
net_cls_subsys_id = -1;
synchronize_rcu();
#endif
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v3 5/6] cgroup: Use IS_MODULE/BUITLIN for net_prio
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev, cgroups
Cc: Daniel Wagner, David S. Miller, Eric Dumazet, Glauber Costa,
Kamezawa Hiroyuki, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1344949343-26090-1-git-send-email-wagi@monom.org>
From: Daniel Wagner <daniel.wagner@bmw-carit.de>
Instead of using #ifdef variation for building the net_prio
in the different configuration use explicit IS_MODULE and
IS_BUILTIN macros.
This allows to reorder in readable way the netprio_cgroup.h header file
so that the common definition of the struct is first followed
by the two different version for task_netprioidx().
Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: netdev@vger.kernel.org
Cc: cgroups@vger.kernel.org
---
include/net/netprio_cgroup.h | 33 ++++++++++++++++-----------------
net/core/netprio_cgroup.c | 6 +++---
net/core/sock.c | 4 +++-
3 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index 2719dec..c43461e 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -17,6 +17,7 @@
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
+#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
struct netprio_map {
struct rcu_head rcu;
@@ -24,19 +25,26 @@ struct netprio_map {
u32 priomap[];
};
-#ifdef CONFIG_CGROUPS
-
struct cgroup_netprio_state {
struct cgroup_subsys_state css;
u32 prioidx;
};
-#ifndef CONFIG_NETPRIO_CGROUP
-extern int net_prio_subsys_id;
-#endif
-
extern void sock_update_netprioidx(struct sock *sk, struct task_struct *task);
+#else
+
+static inline void sock_update_netprioidx(struct sock *sk, struct task_struct *task)
+{
+}
+
+static inline u32 task_netprioidx(struct task_struct *p)
+{
+ return 0;
+}
+
+#endif
+
#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
static inline u32 task_netprioidx(struct task_struct *p)
@@ -54,6 +62,8 @@ static inline u32 task_netprioidx(struct task_struct *p)
#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
+extern int net_prio_subsys_id;
+
static inline u32 task_netprioidx(struct task_struct *p)
{
struct cgroup_netprio_state *state;
@@ -72,17 +82,6 @@ static inline u32 task_netprioidx(struct task_struct *p)
return idx;
}
-#else
-
-static inline u32 task_netprioidx(struct task_struct *p)
-{
- return 0;
-}
-
#endif /* CONFIG_NETPRIO_CGROUP */
-#else
-#define sock_update_netprioidx(sk, task)
-#endif
-
#endif /* _NET_CLS_CGROUP_H */
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 98478aa..238ece6 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -342,7 +342,7 @@ struct cgroup_subsys net_prio_subsys = {
.create = cgrp_create,
.destroy = cgrp_destroy,
.attach = net_prio_attach,
-#ifdef CONFIG_NETPRIO_CGROUP
+#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
.subsys_id = net_prio_subsys_id,
#endif
.base_cftypes = ss_files,
@@ -382,7 +382,7 @@ static int __init init_cgroup_netprio(void)
ret = cgroup_load_subsys(&net_prio_subsys);
if (ret)
goto out;
-#ifndef CONFIG_NETPRIO_CGROUP
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
smp_wmb();
net_prio_subsys_id = net_prio_subsys.subsys_id;
#endif
@@ -402,7 +402,7 @@ static void __exit exit_cgroup_netprio(void)
cgroup_unload_subsys(&net_prio_subsys);
-#ifndef CONFIG_NETPRIO_CGROUP
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
net_prio_subsys_id = -1;
synchronize_rcu();
#endif
diff --git a/net/core/sock.c b/net/core/sock.c
index d2d920e..bdd06af 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -331,7 +331,7 @@ EXPORT_SYMBOL(__sk_backlog_rcv);
int net_cls_subsys_id = -1;
EXPORT_SYMBOL_GPL(net_cls_subsys_id);
#endif
-#if !defined(CONFIG_NETPRIO_CGROUP)
+#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
int net_prio_subsys_id = -1;
EXPORT_SYMBOL_GPL(net_prio_subsys_id);
#endif
@@ -1238,6 +1238,7 @@ void sock_update_classid(struct sock *sk, struct task_struct *task)
EXPORT_SYMBOL(sock_update_classid);
#endif
+#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
void sock_update_netprioidx(struct sock *sk, struct task_struct *task)
{
if (in_interrupt())
@@ -1247,6 +1248,7 @@ void sock_update_netprioidx(struct sock *sk, struct task_struct *task)
}
EXPORT_SYMBOL_GPL(sock_update_netprioidx);
#endif
+#endif
/**
* sk_alloc - All socket objects are allocated here
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* [PATCH v3 6/6] cgroup: Assign subsystem IDs during compile time
From: Daniel Wagner @ 2012-08-14 13:02 UTC (permalink / raw)
To: netdev, cgroups
Cc: Daniel Wagner, David S. Miller, Andrew Morton, Eric Dumazet,
Gao feng, Glauber Costa, Jamal Hadi Salim, John Fastabend,
Kamezawa Hiroyuki, Li Zefan, Neil Horman, Tejun Heo
In-Reply-To: <1344949343-26090-1-git-send-email-wagi@monom.org>
From: Daniel Wagner <daniel.wagner@bmw-carit.de>
We are able to safe some space when we assign the subsystem
IDs at compile time. Instead of allocating per cgroup
cgroup->subsys[CGROUP_SUBSYS_COUNT] where CGROUP_SUBSYS_COUNT is
always 64, we allocate 12 + 1 at max (at this point there are 12
subsystem). The additinal one is the price we have to pay to
distinguish between builtin and module subsystems.
We should only access task_cls_classid() and task_netprioidx()
if the subsystem is ready to be used using jump labels for this.
Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Gao feng <gaofeng@cn.fujitsu.com>
Cc: Glauber Costa <glommer@parallels.com>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: John Fastabend <john.r.fastabend@intel.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: netdev@vger.kernel.org
Cc: cgroups@vger.kernel.org
---
include/linux/cgroup.h | 20 +++++++++++++-------
include/linux/cgroup_subsys.h | 24 ++++++++++++------------
include/net/cls_cgroup.h | 41 ++++++++++++-----------------------------
include/net/netprio_cgroup.h | 43 ++++++++++++-------------------------------
kernel/cgroup.c | 31 +++++++++----------------------
net/core/netprio_cgroup.c | 17 ++++++-----------
net/core/sock.c | 14 ++++++--------
net/sched/cls_cgroup.c | 18 +++++-------------
8 files changed, 75 insertions(+), 133 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c90eaa8..995739f 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -46,16 +46,20 @@ extern const struct file_operations proc_cgroup_operations;
/* Define the enumeration of all builtin cgroup subsystems */
#define SUBSYS(_x) _x ## _subsys_id,
enum cgroup_subsys_id {
+
+#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
+#include <linux/cgroup_subsys.h>
+#undef IS_SUBSYS_ENABLED
+
+ CGROUP_BUILTIN_SUBSYS_COUNT,
+
+#define IS_SUBSYS_ENABLED(option) IS_MODULE(option)
#include <linux/cgroup_subsys.h>
- CGROUP_BUILTIN_SUBSYS_COUNT
+#undef IS_SUBSYS_ENABLED
+
+ CGROUP_SUBSYS_COUNT
};
#undef SUBSYS
-/*
- * This define indicates the maximum number of subsystems that can be loaded
- * at once. We limit to this many since cgroupfs_root has subsys_bits to keep
- * track of all of them.
- */
-#define CGROUP_SUBSYS_COUNT (BITS_PER_BYTE*sizeof(unsigned long))
/* Per-subsystem/per-cgroup state maintained by the system. */
struct cgroup_subsys_state {
@@ -521,7 +525,9 @@ struct cgroup_subsys {
};
#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
+#define IS_SUBSYS_ENABLED(option) IS_ENABLED(option)
#include <linux/cgroup_subsys.h>
+#undef IS_SUBSYS_ENABLED
#undef SUBSYS
static inline struct cgroup_subsys_state *cgroup_subsys_state(
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index dfae957..f204a7a 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -7,73 +7,73 @@
/* */
-#ifdef CONFIG_CPUSETS
+#if IS_SUBSYS_ENABLED(CONFIG_CPUSETS)
SUBSYS(cpuset)
#endif
/* */
-#ifdef CONFIG_CGROUP_DEBUG
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEBUG)
SUBSYS(debug)
#endif
/* */
-#ifdef CONFIG_CGROUP_SCHED
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_SCHED)
SUBSYS(cpu_cgroup)
#endif
/* */
-#ifdef CONFIG_CGROUP_CPUACCT
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_CPUACCT)
SUBSYS(cpuacct)
#endif
/* */
-#ifdef CONFIG_MEMCG
+#if IS_SUBSYS_ENABLED(CONFIG_MEMCG)
SUBSYS(mem_cgroup)
#endif
/* */
-#ifdef CONFIG_CGROUP_DEVICE
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_DEVICE)
SUBSYS(devices)
#endif
/* */
-#ifdef CONFIG_CGROUP_FREEZER
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_FREEZER)
SUBSYS(freezer)
#endif
/* */
-#ifdef CONFIG_NET_CLS_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_NET_CLS_CGROUP)
SUBSYS(net_cls)
#endif
/* */
-#ifdef CONFIG_BLK_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_BLK_CGROUP)
SUBSYS(blkio)
#endif
/* */
-#ifdef CONFIG_CGROUP_PERF
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_PERF)
SUBSYS(perf)
#endif
/* */
-#ifdef CONFIG_NETPRIO_CGROUP
+#if IS_SUBSYS_ENABLED(CONFIG_NETPRIO_CGROUP)
SUBSYS(net_prio)
#endif
/* */
-#ifdef CONFIG_CGROUP_HUGETLB
+#if IS_SUBSYS_ENABLED(CONFIG_CGROUP_HUGETLB)
SUBSYS(hugetlb)
#endif
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index 865ea49..7834fd7 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -16,6 +16,7 @@
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
+#include <linux/jump_label.h>
#if IS_ENABLED(CONFIG_NET_CLS_CGROUP)
@@ -25,27 +26,18 @@ struct cgroup_cls_state
u32 classid;
};
-extern void sock_update_classid(struct sock *sk, struct task_struct *task);
-
-#else
-
-static inline void sock_update_classid(struct sock *sk, struct task_struct *task)
-{
-}
-
-static inline u32 task_cls_classid(struct task_struct *p)
-{
- return 0;
-}
-
-#endif
+extern struct static_key cgroup_cls_enabled;
+#define clscg_enabled static_key_false(&cgroup_cls_enabled)
-#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
+extern void sock_update_classid(struct sock *sk, struct task_struct *task);
static inline u32 task_cls_classid(struct task_struct *p)
{
int classid;
+ if (!clscg_enabled)
+ return 0;
+
rcu_read_lock();
classid = container_of(task_subsys_state(p, net_cls_subsys_id),
struct cgroup_cls_state, css)->classid;
@@ -54,24 +46,15 @@ static inline u32 task_cls_classid(struct task_struct *p)
return classid;
}
-#elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
+#else
-extern int net_cls_subsys_id;
+static inline void sock_update_classid(struct sock *sk, struct task_struct *task)
+{
+}
static inline u32 task_cls_classid(struct task_struct *p)
{
- int id;
- u32 classid = 0;
-
- rcu_read_lock();
- id = rcu_dereference_index_check(net_cls_subsys_id,
- rcu_read_lock_held());
- if (id >= 0)
- classid = container_of(task_subsys_state(p, id),
- struct cgroup_cls_state, css)->classid;
- rcu_read_unlock();
-
- return classid;
+ return 0;
}
#endif
diff --git a/include/net/netprio_cgroup.h b/include/net/netprio_cgroup.h
index c43461e..4ebdae6 100644
--- a/include/net/netprio_cgroup.h
+++ b/include/net/netprio_cgroup.h
@@ -16,6 +16,7 @@
#include <linux/cgroup.h>
#include <linux/hardirq.h>
#include <linux/rcupdate.h>
+#include <linux/jump_label.h>
#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
@@ -30,28 +31,19 @@ struct cgroup_netprio_state {
u32 prioidx;
};
-extern void sock_update_netprioidx(struct sock *sk, struct task_struct *task);
-
-#else
-
-static inline void sock_update_netprioidx(struct sock *sk, struct task_struct *task)
-{
-}
-
-static inline u32 task_netprioidx(struct task_struct *p)
-{
- return 0;
-}
-
-#endif
+extern struct static_key cgroup_netprio_enabled;
+#define netpriocg_enabled static_key_false(&cgroup_netprio_enabled)
-#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
+extern void sock_update_netprioidx(struct sock *sk, struct task_struct *task);
static inline u32 task_netprioidx(struct task_struct *p)
{
struct cgroup_netprio_state *state;
u32 idx;
+ if (!netpriocg_enabled)
+ return 0;
+
rcu_read_lock();
state = container_of(task_subsys_state(p, net_prio_subsys_id),
struct cgroup_netprio_state, css);
@@ -60,26 +52,15 @@ static inline u32 task_netprioidx(struct task_struct *p)
return idx;
}
-#elif IS_MODULE(CONFIG_NETPRIO_CGROUP)
+#else
-extern int net_prio_subsys_id;
+static inline void sock_update_netprioidx(struct sock *sk, struct task_struct *task)
+{
+}
static inline u32 task_netprioidx(struct task_struct *p)
{
- struct cgroup_netprio_state *state;
- int subsys_id;
- u32 idx = 0;
-
- rcu_read_lock();
- subsys_id = rcu_dereference_index_check(net_prio_subsys_id,
- rcu_read_lock_held());
- if (subsys_id >= 0) {
- state = container_of(task_subsys_state(p, subsys_id),
- struct cgroup_netprio_state, css);
- idx = state->prioidx;
- }
- rcu_read_unlock();
- return idx;
+ return 0;
}
#endif /* CONFIG_NETPRIO_CGROUP */
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7981850..aa629ce 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -93,9 +93,12 @@ static DEFINE_MUTEX(cgroup_root_mutex);
* cgroup_mutex.
*/
#define SUBSYS(_x) &_x ## _subsys,
+#define IS_SUBSYS_ENABLED(option) IS_BUILTIN(option)
static struct cgroup_subsys *subsys[CGROUP_SUBSYS_COUNT] = {
#include <linux/cgroup_subsys.h>
};
+#undef IS_SUBSYS_ENABLED
+#undef SUBSYS
#define MAX_CGROUP_ROOT_NAMELEN 64
@@ -1307,7 +1310,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
* raced with a module_delete call, and to the user this is
* essentially a "subsystem doesn't exist" case.
*/
- for (i--; i >= CGROUP_BUILTIN_SUBSYS_COUNT; i--) {
+ for (i--; i > CGROUP_BUILTIN_SUBSYS_COUNT; i--) {
/* drop refcounts only on the ones we took */
unsigned long bit = 1UL << i;
@@ -1324,7 +1327,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
static void drop_parsed_module_refcounts(unsigned long subsys_bits)
{
int i;
- for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
+ for (i = CGROUP_BUILTIN_SUBSYS_COUNT + 1; i < CGROUP_SUBSYS_COUNT; i++) {
unsigned long bit = 1UL << i;
if (!(bit & subsys_bits))
@@ -4322,7 +4325,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
*/
if (ss->module == NULL) {
/* a few sanity checks */
- BUG_ON(ss->subsys_id >= CGROUP_BUILTIN_SUBSYS_COUNT);
+ BUG_ON(ss->subsys_id > CGROUP_BUILTIN_SUBSYS_COUNT);
BUG_ON(subsys[ss->subsys_id] != ss);
return 0;
}
@@ -4330,24 +4333,8 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
/* init base cftset */
cgroup_init_cftsets(ss);
- /*
- * need to register a subsys id before anything else - for example,
- * init_cgroup_css needs it.
- */
mutex_lock(&cgroup_mutex);
- /* find the first empty slot in the array */
- for (i = CGROUP_BUILTIN_SUBSYS_COUNT; i < CGROUP_SUBSYS_COUNT; i++) {
- if (subsys[i] == NULL)
- break;
- }
- if (i == CGROUP_SUBSYS_COUNT) {
- /* maximum number of subsystems already registered! */
- mutex_unlock(&cgroup_mutex);
- return -EBUSY;
- }
- /* assign ourselves the subsys_id */
- ss->subsys_id = i;
- subsys[i] = ss;
+ subsys[ss->subsys_id] = ss;
/*
* no ss->create seems to need anything important in the ss struct, so
@@ -4356,7 +4343,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
css = ss->create(dummytop);
if (IS_ERR(css)) {
/* failure case - need to deassign the subsys[] slot. */
- subsys[i] = NULL;
+ subsys[ss->subsys_id] = NULL;
mutex_unlock(&cgroup_mutex);
return PTR_ERR(css);
}
@@ -4372,7 +4359,7 @@ int __init_or_module cgroup_load_subsys(struct cgroup_subsys *ss)
if (ret) {
dummytop->subsys[ss->subsys_id] = NULL;
ss->destroy(dummytop);
- subsys[i] = NULL;
+ subsys[ss->subsys_id] = NULL;
mutex_unlock(&cgroup_mutex);
return ret;
}
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index 238ece6..c3f93a1 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -155,6 +155,9 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
goto out;
}
+ if (!netpriocg_enabled && !cgrp->parent)
+ static_key_slow_inc(&cgroup_netprio_enabled);
+
ret = update_netdev_tables();
if (ret < 0) {
put_prioidx(cs->prioidx);
@@ -173,6 +176,9 @@ static void cgrp_destroy(struct cgroup *cgrp)
struct net_device *dev;
struct netprio_map *map;
+ if (netpriocg_enabled && !cgrp->parent)
+ static_key_slow_dec(&cgroup_netprio_enabled);
+
cs = cgrp_netprio_state(cgrp);
rtnl_lock();
for_each_netdev(&init_net, dev) {
@@ -342,9 +348,7 @@ struct cgroup_subsys net_prio_subsys = {
.create = cgrp_create,
.destroy = cgrp_destroy,
.attach = net_prio_attach,
-#if IS_BUILTIN(CONFIG_NETPRIO_CGROUP)
.subsys_id = net_prio_subsys_id,
-#endif
.base_cftypes = ss_files,
.module = THIS_MODULE
};
@@ -382,10 +386,6 @@ static int __init init_cgroup_netprio(void)
ret = cgroup_load_subsys(&net_prio_subsys);
if (ret)
goto out;
-#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
- smp_wmb();
- net_prio_subsys_id = net_prio_subsys.subsys_id;
-#endif
register_netdevice_notifier(&netprio_device_notifier);
@@ -402,11 +402,6 @@ static void __exit exit_cgroup_netprio(void)
cgroup_unload_subsys(&net_prio_subsys);
-#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
- net_prio_subsys_id = -1;
- synchronize_rcu();
-#endif
-
rtnl_lock();
for_each_netdev(&init_net, dev) {
old = rtnl_dereference(dev->priomap);
diff --git a/net/core/sock.c b/net/core/sock.c
index bdd06af..301243b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -326,15 +326,13 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
}
EXPORT_SYMBOL(__sk_backlog_rcv);
-#if defined(CONFIG_CGROUPS)
-#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
-int net_cls_subsys_id = -1;
-EXPORT_SYMBOL_GPL(net_cls_subsys_id);
-#endif
-#if IS_MODULE(CONFIG_NETPRIO_CGROUP)
-int net_prio_subsys_id = -1;
-EXPORT_SYMBOL_GPL(net_prio_subsys_id);
+#if IS_ENABLED(CONFIG_NET_CLS_CGROUP)
+struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
#endif
+#if IS_ENABLED(CONFIG_NETPRIO_CGROUP)
+struct static_key cgroup_netprio_enabled = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(cgroup_netprio_enabled);
#endif
static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 9ffe9b5..80f71cd 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -45,12 +45,17 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
if (cgrp->parent)
cs->classid = cgrp_cls_state(cgrp->parent)->classid;
+ else if (!clscg_enabled)
+ static_key_slow_inc(&cgroup_cls_enabled);
return &cs->css;
}
static void cgrp_destroy(struct cgroup *cgrp)
{
+ if (!cgrp->parent && clscg_enabled)
+ static_key_slow_dec(&cgroup_cls_enabled);
+
kfree(cgrp_cls_state(cgrp));
}
@@ -115,9 +120,7 @@ struct cgroup_subsys net_cls_subsys = {
.create = cgrp_create,
.destroy = cgrp_destroy,
.attach = cgrp_attach,
-#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP)
.subsys_id = net_cls_subsys_id,
-#endif
.base_cftypes = ss_files,
.module = THIS_MODULE,
};
@@ -321,12 +324,6 @@ static int __init init_cgroup_cls(void)
if (ret)
goto out;
-#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
- /* We can't use rcu_assign_pointer because this is an int. */
- smp_wmb();
- net_cls_subsys_id = net_cls_subsys.subsys_id;
-#endif
-
ret = register_tcf_proto_ops(&cls_cgroup_ops);
if (ret)
cgroup_unload_subsys(&net_cls_subsys);
@@ -339,11 +336,6 @@ static void __exit exit_cgroup_cls(void)
{
unregister_tcf_proto_ops(&cls_cgroup_ops);
-#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
- net_cls_subsys_id = -1;
- synchronize_rcu();
-#endif
-
cgroup_unload_subsys(&net_cls_subsys);
}
--
1.7.12.rc1.16.g05a20c8
^ permalink raw reply related
* Re: [PATCH v3 0/6] cgroup cls & netprio 'cleanups'
From: Neil Horman @ 2012-08-14 13:10 UTC (permalink / raw)
To: Daniel Wagner
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Daniel Wagner, David S. Miller, Al Viro, Andrew Morton,
Eric Dumazet, Gao feng, Glauber Costa, Jamal Hadi Salim,
John Fastabend, Kamezawa Hiroyuki, Li Zefan, Tejun Heo, Tim Chen
In-Reply-To: <1344949343-26090-1-git-send-email-wagi-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
On Tue, Aug 14, 2012 at 03:02:16PM +0200, Daniel Wagner wrote:
> From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
>
> Hi,
>
> Sorry for the delay on updating this series. The usual
> excuse apply here.
>
> I saw that John is busy improving net_prio so I took the
> liberty to port his changes to net_cls (#1-3). Patch #3 will
> collide with John's unapplied patches. I am happy
> to rebase this series if needed.
>
> Patch #4 and #5 improve the readability with using
> IS_MODULE/BUILTIN macros. This patches prepare the last
> patch.
>
> Patch #6 removes support for assigning subsystem IDs during
> runtime. As it turns out this is not really needed. By doing
> so we are able to free some unused memory.
>
> The patches are against net-next.
>
> cheers,
> daniel
>
These aren't so much 'cleanups' as feature enhancements and fixes for the first
pass of those enhancements (at least in the case of the net_prio cgroup). I've
nothing against them, but since we're still going through some churn on the
net_prio variant, it may be best to wait until thats settled before moving them
over to net_cls.
Neil
^ permalink raw reply
* Re: [patch net-next 01/16] net: introduce upper device lists
From: Flavio Leitner @ 2012-08-14 13:14 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, edumazet, faisal.latif, roland, sean.hefty,
hal.rosenstock, fubar, andy, divy, jitendra.kalsaria, sony.chacko,
linux-driver, kaber, ursula.braun, blaschka, linux390, shemminger,
bhutchings, therbert, xiyou.wangcong, joe, gregory.v.rose,
john.r.fastabend, linux-rdma, linux-kernel, linux-s390, bridge
In-Reply-To: <20120814122433.GB1661@minipsycho.brq.redhat.com>
On Tue, 14 Aug 2012 14:24:33 +0200
Jiri Pirko <jiri@resnulli.us> wrote:
> Mon, Aug 13, 2012 at 07:52:17PM CEST, fbl@redhat.com wrote:
> >On Mon, 13 Aug 2012 17:27:00 +0200
> >Jiri Pirko <jiri@resnulli.us> wrote:
> >> + /*
> >> + * To prevent loops, check if dev is not upper device to upper_dev.
> >> + */
> >> + if (__netdev_has_upper_dev(upper_dev, dev, true))
> >> + return -EBUSY;
> >> +
> >> + if (__netdev_find_upper(dev, upper_dev))
> >> + return -EEXIST;
> >
> >__netdev_has_upper_dev() can go all the way up finding the device and
> >the __netdev_find_upper() just check the first level.
>
>
> I do not think this ordering is somewhat inportant.
it's not the order, see below:
> >I think it would be better to use:
> >__netdev_find_upper_dev(,,deep=true/false)
> >__netdev_has_upper(,)
It's their names. Currently, the function ..._find_... look at
one level only, while the function ..._has_... does one or more
levels. I think it's better to swap 'has' and 'find' in their names:
__netdev_find_upper_dev(,,deep=true/false) <-- find in all levels
__netdev_has_upper(,) <-- check only the one level.
fbl
^ permalink raw reply
* Re: [PATCH v3 0/6] cgroup cls & netprio 'cleanups'
From: Daniel Wagner @ 2012-08-14 13:25 UTC (permalink / raw)
To: Neil Horman
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Daniel Wagner, David S. Miller, Al Viro, Andrew Morton,
Eric Dumazet, Gao feng, Glauber Costa, Jamal Hadi Salim,
John Fastabend, Kamezawa Hiroyuki, Li Zefan, Tejun Heo, Tim Chen
In-Reply-To: <20120814131035.GC18731-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
Hi Neil,
On 14.08.2012 15:10, Neil Horman wrote:
> On Tue, Aug 14, 2012 at 03:02:16PM +0200, Daniel Wagner wrote:
>> From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
>>
>> Hi,
>>
>> Sorry for the delay on updating this series. The usual
>> excuse apply here.
>>
>> I saw that John is busy improving net_prio so I took the
>> liberty to port his changes to net_cls (#1-3). Patch #3 will
>> collide with John's unapplied patches. I am happy
>> to rebase this series if needed.
>>
>> Patch #4 and #5 improve the readability with using
>> IS_MODULE/BUILTIN macros. This patches prepare the last
>> patch.
>>
>> Patch #6 removes support for assigning subsystem IDs during
>> runtime. As it turns out this is not really needed. By doing
>> so we are able to free some unused memory.
>>
>> The patches are against net-next.
>>
>> cheers,
>> daniel
>>
> These aren't so much 'cleanups' as feature enhancements and fixes for the first
> pass of those enhancements (at least in the case of the net_prio cgroup).
Sorry about that. I wanted to keep the series title, so that someone
looking up older versions find it.
> I've nothing against them, but since we're still going through some churn on the
> net_prio variant, it may be best to wait until thats settled before moving them
> over to net_cls.
Sure, I can update this series when the net_prio controller changes have
settled down.
I just wonder if it wouldn't make sense to merge them together.
Obviously, that will break the user space which is not a good thing but
having a controller per socket option is not good either.
cheers,
daniel
^ permalink raw reply
* [PATCH] libceph: Fix sparse warning
From: Iulius Curt @ 2012-08-14 13:27 UTC (permalink / raw)
To: davem; +Cc: sage, ceph-devel, netdev, dbaluta, Iulius Curt, Iulius Curt
From: Iulius Curt <iulius.curt@gmail.com>
Make ceph_monc_do_poolop() static to remove the following sparse warning:
* net/ceph/mon_client.c:616:5: warning: symbol 'ceph_monc_do_poolop' was not
declared. Should it be static?
Signed-off-by: Iulius Curt <icurt@ixiacom.com>
---
net/ceph/mon_client.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 105d533..3875c60 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -613,7 +613,7 @@ bad:
/*
* Do a synchronous pool op.
*/
-int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op,
+static int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op,
u32 pool, u64 snapid,
char *buf, int len)
{
--
1.7.9.5
^ permalink raw reply related
* Re: [Xen-devel] [PATCH] netvm: check for page == NULL when propogating the skb->pfmemalloc flag
From: Konrad Rzeszutek Wilk @ 2012-08-14 13:28 UTC (permalink / raw)
To: Mel Gorman
Cc: David Miller, Ian Campbell, xen-devel, netdev, linux-kernel,
linux-mm, konrad, akpm
In-Reply-To: <20120814100522.GL4177@suse.de>
On Tue, Aug 14, 2012 at 11:05:22AM +0100, Mel Gorman wrote:
> On Mon, Aug 13, 2012 at 11:41:44AM -0400, Konrad Rzeszutek Wilk wrote:
> > On Wed, Aug 08, 2012 at 03:50:46PM -0700, David Miller wrote:
> > > From: Mel Gorman <mgorman@suse.de>
> > > Date: Tue, 7 Aug 2012 09:55:55 +0100
> > >
> > > > Commit [c48a11c7: netvm: propagate page->pfmemalloc to skb] is responsible
> > > > for the following bug triggered by a xen network driver
> > > ...
> > > > The problem is that the xenfront driver is passing a NULL page to
> > > > __skb_fill_page_desc() which was unexpected. This patch checks that
> > > > there is a page before dereferencing.
> > > >
> > > > Reported-and-Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > > > Signed-off-by: Mel Gorman <mgorman@suse.de>
> > >
> > > That call to __skb_fill_page_desc() in xen-netfront.c looks completely bogus.
> > > It's the only driver passing NULL here.
> >
> > It looks to be passing a valid page pointer (at least by looking
> > at the code) so I am not sure how it got turned in a NULL.
> >
>
> Are we looking at different code bases? I see this and I was assuming it
> was the source of the bug.
>
> __skb_fill_page_desc(skb, 0, NULL, 0, 0);
Yes! Well, that is embarrassing. I was looking at the first invocation of
__skb_fill_page_desc (which is in xennet_alloc_rx_buffers) <sigh>
>
> --
> Mel Gorman
> SUSE Labs
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* [PATCH] net: remove wrong initialization for snd_wl1
From: Razvan Ghitulete @ 2012-08-14 13:30 UTC (permalink / raw)
To: davem, kuznet, jmorris, yoshfuji, kaber, netdev; +Cc: dbaluta, Razvan Ghitulete
The field tp->snd_wl1 is twice initialized, the second time
seems to be wrong as it may overwrite any update in tcp_ack.
Signed-off-by: Razvan Ghitulete <rghitulete@ixiacom.com>
---
net/ipv4/tcp_input.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index fa2c2c2..c423317 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5744,7 +5744,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
TCP_ECN_rcv_synack(tp, th);
- tp->snd_wl1 = TCP_SKB_CB(skb)->seq;
+ tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
tcp_ack(sk, skb, FLAG_SLOWPATH);
/* Ok.. it's good. Set up sequence numbers and
@@ -5757,7 +5757,6 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
* never scaled.
*/
tp->snd_wnd = ntohs(th->window);
- tcp_init_wl(tp, TCP_SKB_CB(skb)->seq);
if (!tp->rx_opt.wscale_ok) {
tp->rx_opt.snd_wscale = tp->rx_opt.rcv_wscale = 0;
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v3 0/6] cgroup cls & netprio 'cleanups'
From: Neil Horman @ 2012-08-14 13:30 UTC (permalink / raw)
To: Daniel Wagner
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Daniel Wagner, David S. Miller, Al Viro, Andrew Morton,
Eric Dumazet, Gao feng, Glauber Costa, Jamal Hadi Salim,
John Fastabend, Kamezawa Hiroyuki, Li Zefan, Tejun Heo, Tim Chen
In-Reply-To: <502A51DE.7040809-kQCPcA+X3s7YtjvyW6yDsg@public.gmane.org>
On Tue, Aug 14, 2012 at 03:25:50PM +0200, Daniel Wagner wrote:
> Hi Neil,
>
> On 14.08.2012 15:10, Neil Horman wrote:
> >On Tue, Aug 14, 2012 at 03:02:16PM +0200, Daniel Wagner wrote:
> >>From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> >>
> >>Hi,
> >>
> >>Sorry for the delay on updating this series. The usual
> >>excuse apply here.
> >>
> >>I saw that John is busy improving net_prio so I took the
> >>liberty to port his changes to net_cls (#1-3). Patch #3 will
> >>collide with John's unapplied patches. I am happy
> >>to rebase this series if needed.
> >>
> >>Patch #4 and #5 improve the readability with using
> >>IS_MODULE/BUILTIN macros. This patches prepare the last
> >>patch.
> >>
> >>Patch #6 removes support for assigning subsystem IDs during
> >>runtime. As it turns out this is not really needed. By doing
> >>so we are able to free some unused memory.
> >>
> >>The patches are against net-next.
> >>
> >>cheers,
> >>daniel
> >>
> >These aren't so much 'cleanups' as feature enhancements and fixes for the first
> >pass of those enhancements (at least in the case of the net_prio cgroup).
>
> Sorry about that. I wanted to keep the series title, so that someone
> looking up older versions find it.
>
That makes sense, but it would be best until we acked the the version going into
net_prio, otherwise we maybe tracking regressions in two places rather than one.
> >I've nothing against them, but since we're still going through some churn on the
> >net_prio variant, it may be best to wait until thats settled before moving them
> >over to net_cls.
>
> Sure, I can update this series when the net_prio controller changes
> have settled down.
>
Thank you, I think thats a good idea.
> I just wonder if it wouldn't make sense to merge them together.
> Obviously, that will break the user space which is not a good thing
> but having a controller per socket option is not good either.
>
This has been discussed (although perhaps not on list) before. I don't think
we're going to see lots of cgroups for socket options. most of them have proc
tunables, priroity and classification dont. We could merge the two controllers,
but as you said it breaks users space which is a non-starter. It also doesn't
really buy us anything, as people want to be able to set priority and
classification independently, so we either use two controllers, or one
controller with twice as many cgroup instances (one for each combination of
priroity/class that an admin wants).
I'll ping you when the net_prio stuff settles out.
Regards
Neil
> cheers,
> daniel
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox