* [net-next PATCH v1 3/7] net: add fdb generic dump routine
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This adds a generic dump routine drivers can call. It
should be sufficient to handle any bridging model that
uses the unicast address list. This should be most SR-IOV
enabled NICs.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
net/core/rtnetlink.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index d6ce728..2bb4f59 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2088,6 +2088,77 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
return err;
}
+static int nlmsg_populate_fdb(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int *idx,
+ struct netdev_hw_addr_list *list)
+{
+ struct netdev_hw_addr *ha;
+ struct ndmsg *ndm;
+ struct nlmsghdr *nlh;
+ u32 pid, seq;
+
+ pid = NETLINK_CB(cb->skb).pid;
+ seq = cb->nlh->nlmsg_seq;
+
+ list_for_each_entry(ha, &list->list, list) {
+ if (*idx < cb->args[0])
+ goto skip;
+
+ nlh = nlmsg_put(skb, pid, seq,
+ RTM_NEWNEIGH, sizeof(*ndm), NLM_F_MULTI);
+ if (!nlh)
+ break;
+
+ ndm = nlmsg_data(nlh);
+ ndm->ndm_family = AF_BRIDGE;
+ ndm->ndm_pad1 = 0;
+ ndm->ndm_pad2 = 0;
+ ndm->ndm_flags = NTF_SELF;
+ ndm->ndm_type = 0;
+ ndm->ndm_ifindex = dev->ifindex;
+ ndm->ndm_state = NUD_PERMANENT;
+
+ if (nla_put(skb, NDA_LLADDR, ETH_ALEN, ha->addr))
+ goto nla_put_failure;
+
+ nlmsg_end(skb, nlh);
+skip:
+ *idx += 1;
+ }
+ return 0;
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+ return -ENOMEM;
+}
+
+/**
+ * ndo_dflt_fdb_dump: default netdevice operation to dump an FDB table.
+ * @nlh: netlink message header
+ * @dev: netdevice
+ *
+ * Default netdevice operation to dump the existing unicast address list.
+ * Returns zero on success.
+ */
+int ndo_dflt_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx)
+{
+ int err;
+
+ netif_addr_lock_bh(dev);
+ err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc);
+ if (err)
+ goto out;
+ nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->mc);
+out:
+ netif_addr_unlock_bh(dev);
+ return idx;
+}
+EXPORT_SYMBOL(ndo_dflt_fdb_dump);
+
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
int idx = 0;
^ permalink raw reply related
* [net-next PATCH v1 4/7] ixgbe: enable FDB netdevice ops
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
Enable FDB ops on ixgbe when in SR-IOV mode.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 71 +++++++++++++++++++++++++
1 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 3e26b1f..8b37395 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -6681,6 +6681,74 @@ static int ixgbe_set_features(struct net_device *netdev,
return 0;
}
+static int ixgbe_ndo_fdb_add(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 flags)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ int err = -EOPNOTSUPP;
+
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ pr_info("%s: FDB only supports static addresses\n",
+ ixgbe_driver_name);
+ return -EINVAL;
+ }
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_add_excl(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_add_excl(dev, addr);
+ else
+ err = -EINVAL;
+ }
+
+ /* Only return duplicate errors if NLM_F_EXCL is set */
+ if (err == -EEXIST && !(flags & NLM_F_EXCL))
+ err = 0;
+
+ return err;
+}
+
+static int ixgbe_ndo_fdb_del(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+ int err = -EOPNOTSUPP;
+
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ pr_info("%s: FDB only supports static addresses\n",
+ ixgbe_driver_name);
+ return -EINVAL;
+ }
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_del(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_del(dev, addr);
+ else
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int ixgbe_ndo_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *dev,
+ int idx)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(dev);
+
+ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
+ idx = ndo_dflt_fdb_dump(skb, cb, dev, idx);
+
+ return idx;
+}
+
static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_open = ixgbe_open,
.ndo_stop = ixgbe_close,
@@ -6717,6 +6785,9 @@ static const struct net_device_ops ixgbe_netdev_ops = {
#endif /* IXGBE_FCOE */
.ndo_set_features = ixgbe_set_features,
.ndo_fix_features = ixgbe_fix_features,
+ .ndo_fdb_add = ixgbe_ndo_fdb_add,
+ .ndo_fdb_del = ixgbe_ndo_fdb_del,
+ .ndo_fdb_dump = ixgbe_ndo_fdb_dump,
};
static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
^ permalink raw reply related
* [net-next PATCH v1 5/7] ixgbe: allow RAR table to be updated in promisc mode
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This allows RAR table updates while in promiscuous. With
SR-IOV enabled it is valuable to allow the RAR table to
be updated even when in promisc mode to configure forwarding
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 21 +++++++++++----------
1 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8b37395..25a7ed9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -3462,16 +3462,17 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
}
ixgbe_vlan_filter_enable(adapter);
hw->addr_ctrl.user_set_promisc = false;
- /*
- * Write addresses to available RAR registers, if there is not
- * sufficient space to store all the addresses then enable
- * unicast promiscuous mode
- */
- count = ixgbe_write_uc_addr_list(netdev);
- if (count < 0) {
- fctrl |= IXGBE_FCTRL_UPE;
- vmolr |= IXGBE_VMOLR_ROPE;
- }
+ }
+
+ /*
+ * Write addresses to available RAR registers, if there is not
+ * sufficient space to store all the addresses then enable
+ * unicast promiscuous mode
+ */
+ count = ixgbe_write_uc_addr_list(netdev);
+ if (count < 0) {
+ fctrl |= IXGBE_FCTRL_UPE;
+ vmolr |= IXGBE_VMOLR_ROPE;
}
if (adapter->num_vfs) {
^ permalink raw reply related
* [net-next PATCH v1 6/7] ixgbe: UTA table incorrectly programmed
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
From: Greg Rose <gregory.v.rose@intel.com>
The UTA table was being set to the functional equivalent of promiscuous
mode. This was resulting in traffic from the virtual function being
flooded onto the wire and the PF device. This resulted in additional
overhead for VF traffic sent to the network and in the case of traffic
sent to the PF or another VF resulted in unwanted packets on the wire.
This was actually not the intended behavior. Now that we can program
the embedded switch correctly we can remove this snippit of code. Users
who want to support this should configure the FDB correctly using the
FDB ops.
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 29 -------------------------
1 files changed, 0 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 25a7ed9..10606bd 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -2904,33 +2904,6 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter,
IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl);
}
-/**
- * ixgbe_set_uta - Set unicast filter table address
- * @adapter: board private structure
- *
- * The unicast table address is a register array of 32-bit registers.
- * The table is meant to be used in a way similar to how the MTA is used
- * however due to certain limitations in the hardware it is necessary to
- * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous
- * enable bit to allow vlan tag stripping when promiscuous mode is enabled
- **/
-static void ixgbe_set_uta(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- int i;
-
- /* The UTA table only exists on 82599 hardware and newer */
- if (hw->mac.type < ixgbe_mac_82599EB)
- return;
-
- /* we only need to do this if VMDq is enabled */
- if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
- return;
-
- for (i = 0; i < 128; i++)
- IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0);
-}
-
#define IXGBE_MAX_RX_DESC_POLL 10
static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
struct ixgbe_ring *ring)
@@ -3224,8 +3197,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
/* Program registers for the distribution of queues */
ixgbe_setup_mrqc(adapter);
- ixgbe_set_uta(adapter);
-
/* set_rx_buffer_len must be called before ring initialization */
ixgbe_set_rx_buffer_len(adapter);
^ permalink raw reply related
* [net-next PATCH v1 7/7] macvlan: add FDB bridge ops and new macvlan mode
From: John Fastabend @ 2012-04-09 22:00 UTC (permalink / raw)
To: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher
Cc: netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
This adds a new macvlan mode MACVLAN_PASSTHRU_NOPROMISC
this mode acts the same as the original passthru mode _except_
it does not set promiscuous mode on the lowerdev. Because the
lowerdev is not put in promiscuous mode any unicast or multicast
addresses the device should receive must be explicitely added
with the FDB bridge ops. In many use cases the management stack
will know the mac addresses needed (maybe negotiated via EVB/VDP)
or may require only receiving known "good" mac addresses. This
mode with the FDB ops supports this usage model.
This patch is a result of Roopa Prabhu's work. Follow up
patches are needed for VEPA and VEB macvlan modes.
CC: Roopa Prabhu <roprabhu@cisco.com>
CC: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
---
drivers/net/macvlan.c | 60 ++++++++++++++++++++++++++++++++++++++++++-----
include/linux/if_link.h | 1 +
2 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index b17fc90..9892d8d 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -181,6 +181,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
MACVLAN_MODE_PRIVATE |
MACVLAN_MODE_VEPA |
MACVLAN_MODE_PASSTHRU|
+ MACVLAN_MODE_PASSTHRU_NOPROMISC |
MACVLAN_MODE_BRIDGE);
else if (src->mode == MACVLAN_MODE_VEPA)
/* flood to everyone except source */
@@ -312,7 +313,8 @@ static int macvlan_open(struct net_device *dev)
int err;
if (vlan->port->passthru) {
- dev_set_promiscuity(lowerdev, 1);
+ if (vlan->mode == MACVLAN_MODE_PASSTHRU)
+ dev_set_promiscuity(lowerdev, 1);
goto hash_add;
}
@@ -344,12 +346,15 @@ static int macvlan_stop(struct net_device *dev)
struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;
+ dev_uc_unsync(lowerdev, dev);
+ dev_mc_unsync(lowerdev, dev);
+
if (vlan->port->passthru) {
- dev_set_promiscuity(lowerdev, -1);
+ if (vlan->mode == MACVLAN_MODE_PASSTHRU)
+ dev_set_promiscuity(lowerdev, 1);
goto hash_del;
}
- dev_mc_unsync(lowerdev, dev);
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(lowerdev, -1);
@@ -399,10 +404,11 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
}
-static void macvlan_set_multicast_list(struct net_device *dev)
+static void macvlan_set_mac_lists(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
+ dev_uc_sync(vlan->lowerdev, dev);
dev_mc_sync(vlan->lowerdev, dev);
}
@@ -542,6 +548,43 @@ static int macvlan_vlan_rx_kill_vid(struct net_device *dev,
return 0;
}
+static int macvlan_fdb_add(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 flags)
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+ int err = -EINVAL;
+
+ if (!vlan->port->passthru)
+ return -EOPNOTSUPP;
+
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_add_excl(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_add_excl(dev, addr);
+
+ return err;
+}
+
+static int macvlan_fdb_del(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr)
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+ int err = -EINVAL;
+
+ if (!vlan->port->passthru)
+ return -EOPNOTSUPP;
+
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_del(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_del(dev, addr);
+
+ return err;
+}
+
static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
@@ -572,11 +615,14 @@ static const struct net_device_ops macvlan_netdev_ops = {
.ndo_change_mtu = macvlan_change_mtu,
.ndo_change_rx_flags = macvlan_change_rx_flags,
.ndo_set_mac_address = macvlan_set_mac_address,
- .ndo_set_rx_mode = macvlan_set_multicast_list,
+ .ndo_set_rx_mode = macvlan_set_mac_lists,
.ndo_get_stats64 = macvlan_dev_get_stats64,
.ndo_validate_addr = eth_validate_addr,
.ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid,
+ .ndo_fdb_add = macvlan_fdb_add,
+ .ndo_fdb_del = macvlan_fdb_del,
+ .ndo_fdb_dump = ndo_dflt_fdb_dump,
};
void macvlan_common_setup(struct net_device *dev)
@@ -648,6 +694,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
case MACVLAN_MODE_VEPA:
case MACVLAN_MODE_BRIDGE:
case MACVLAN_MODE_PASSTHRU:
+ case MACVLAN_MODE_PASSTHRU_NOPROMISC:
break;
default:
return -EINVAL;
@@ -711,7 +758,8 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
if (data && data[IFLA_MACVLAN_MODE])
vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
- if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
+ if ((vlan->mode == MACVLAN_MODE_PASSTHRU) ||
+ (vlan->mode == MACVLAN_MODE_PASSTHRU_NOPROMISC)) {
if (port->count)
return -EINVAL;
port->passthru = true;
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 2f4fa93..db67b9d 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -265,6 +265,7 @@ enum macvlan_mode {
MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
+ MACVLAN_MODE_PASSTHRU_NOPROMISC = 16, /* passthru without promisc */
};
/* SR-IOV virtual function management section */
^ permalink raw reply related
* Re: [net-next PATCH v1 0/7] Managing the forwarding database(FDB)
From: Stephen Hemminger @ 2012-04-09 22:15 UTC (permalink / raw)
To: John Fastabend
Cc: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher, netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409215419.3288.50790.stgit@jf-dev1-dcblab>
On Mon, 09 Apr 2012 15:00:11 -0700
John Fastabend <john.r.fastabend@intel.com> wrote:
> The following series is a submission for net-next to allow
> embedded switches and other stacked devices other then the
> Linux bridge to manage a forwarding database.
>
> This was previously posted here (where it was deferred for
> more review and testing)
>
> http://lists.openwall.net/netdev/2012/03/19/26
>
> This series adds macvlan support per discussions with Roopa
> and Michael. Also ixgbe was updated to support adding multicast
> addresses per request from Greg Rose.
>
> Finally cleanups in the generic dump routines were added
> for multicast to support ixgbe and macvlan use cases.
>
> Thanks to everyone for the helpful review and comments. As
> always any comments/feedback welcome.
>
> .John
>
> ---
>
> Greg Rose (1):
> ixgbe: UTA table incorrectly programmed
>
> John Fastabend (6):
> macvlan: add FDB bridge ops and new macvlan mode
> ixgbe: allow RAR table to be updated in promisc mode
> ixgbe: enable FDB netdevice ops
> net: add fdb generic dump routine
> net: addr_list: add exclusive dev_uc_add and dev_mc_add
> net: add generic PF_BRIDGE:RTM_ FDB hooks
>
>
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 121 ++++++++++----
> drivers/net/macvlan.c | 60 ++++++-
> include/linux/if_link.h | 1
> include/linux/neighbour.h | 3
> include/linux/netdevice.h | 28 +++
> include/linux/rtnetlink.h | 4
> net/bridge/br_device.c | 3
> net/bridge/br_fdb.c | 128 ++++-----------
> net/bridge/br_netlink.c | 12 -
> net/bridge/br_private.h | 15 +-
> net/core/dev_addr_lists.c | 97 ++++++++++--
> net/core/rtnetlink.c | 209 +++++++++++++++++++++++++
> 12 files changed, 508 insertions(+), 173 deletions(-)
>
How do statistics work in this case? What if you wanted to do BRIDGE MIB?
^ permalink raw reply
* Re: [net-next PATCH v1 0/7] Managing the forwarding database(FDB)
From: John Fastabend @ 2012-04-09 22:32 UTC (permalink / raw)
To: Stephen Hemminger
Cc: roprabhu, mst, stephen.hemminger, davem, hadi, bhutchings,
jeffrey.t.kirsher, netdev, gregory.v.rose, krkumar2, sri
In-Reply-To: <20120409151501.23ff83f6@nehalam.linuxnetplumber.net>
On 4/9/2012 3:15 PM, Stephen Hemminger wrote:
> On Mon, 09 Apr 2012 15:00:11 -0700
> John Fastabend <john.r.fastabend@intel.com> wrote:
>
>> The following series is a submission for net-next to allow
>> embedded switches and other stacked devices other then the
>> Linux bridge to manage a forwarding database.
>>
>> This was previously posted here (where it was deferred for
>> more review and testing)
>>
>> http://lists.openwall.net/netdev/2012/03/19/26
>>
>> This series adds macvlan support per discussions with Roopa
>> and Michael. Also ixgbe was updated to support adding multicast
>> addresses per request from Greg Rose.
>>
>> Finally cleanups in the generic dump routines were added
>> for multicast to support ixgbe and macvlan use cases.
>>
>> Thanks to everyone for the helpful review and comments. As
>> always any comments/feedback welcome.
>>
>> .John
>>
>> ---
>>
>> Greg Rose (1):
>> ixgbe: UTA table incorrectly programmed
>>
>> John Fastabend (6):
>> macvlan: add FDB bridge ops and new macvlan mode
>> ixgbe: allow RAR table to be updated in promisc mode
>> ixgbe: enable FDB netdevice ops
>> net: add fdb generic dump routine
>> net: addr_list: add exclusive dev_uc_add and dev_mc_add
>> net: add generic PF_BRIDGE:RTM_ FDB hooks
>>
>>
>> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 121 ++++++++++----
>> drivers/net/macvlan.c | 60 ++++++-
>> include/linux/if_link.h | 1
>> include/linux/neighbour.h | 3
>> include/linux/netdevice.h | 28 +++
>> include/linux/rtnetlink.h | 4
>> net/bridge/br_device.c | 3
>> net/bridge/br_fdb.c | 128 ++++-----------
>> net/bridge/br_netlink.c | 12 -
>> net/bridge/br_private.h | 15 +-
>> net/core/dev_addr_lists.c | 97 ++++++++++--
>> net/core/rtnetlink.c | 209 +++++++++++++++++++++++++
>> 12 files changed, 508 insertions(+), 173 deletions(-)
>>
>
> How do statistics work in this case? What if you wanted to do BRIDGE MIB?
I expect we will need to do the same sort of thing for PF_BRIDGE:RTM_GETLINK
to dump the statistics for an embedded or stacked bridge. This series only
gets the forwarding database setup. All the other entries in the MIB still
need to be populated. What I would like is to be able to write a BRIDGE MIB
implementation and have it work with any of the bridging components in the
linux kernel. But I don't think that should block this series.
Make sense?
Based on a quick scan I'm not sure the existing net/bridge code has one place
to pull all the stats from anyways looks like you might have to read some sysfs
entries AND do some netlink commands. I would have to check that though. It is
on my todo list to create a bridge mib for some of the EVB cases. Of course if
someone else got to it that would be great.
.John
^ permalink raw reply
* [PATCH v3 0/2] get rid of populate for memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A
[ v3: fix bug with failed initialization, seen by Tejun ]
Hi Tejun,
Let me know if the following is acceptable. Turns out the only
operation with a side effect we do after the last failure spot,
is a get on the parent memcg, and the setup of our very own refcnt.
Both of them can be dealt with a mem_cgroup_put in the beginning
of the failure path. So I felt no need for any code reordering.
People from the memcg side, please verify if this is indeed
okay.
I actually tested it with some test code to force memcg_kmem_init()
to fail, and it seems to go all right.
I'll be happy to address any other problems you spot.
Glauber Costa (2):
cgroup: pass struct mem_cgroup instead of struct cgroup to socket
memcg
cgroup: get rid of populate for memcg
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 39 ++++++++++++++++++---------------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 33 insertions(+), 38 deletions(-)
--
1.7.7.6
^ permalink raw reply
* [PATCH v3 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Johannes Weiner, Michal Hocko
In-Reply-To: <1334010994-23301-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The only reason cgroup was used, was to be consistent with the populate()
interface. Now that we're getting rid of it, not only we no longer need
it, but we also *can't* call it this way.
Since we will no longer rely on populate(), this will be called from
create(). During create, the association between struct mem_cgroup
and struct cgroup does not yet exist, since cgroup internals hasn't
yet initialized its bookkeeping. This means we would not be able
to draw the memcg pointer from the cgroup pointer in these
functions, which is highly undesirable.
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
---
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 24 +++++++++---------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index a6ba1f8..b3ebe6b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -70,16 +70,16 @@
struct cgroup;
struct cgroup_subsys;
#ifdef CONFIG_NET
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp);
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg);
#else
static inline
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
static inline
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -900,9 +900,9 @@ struct proto {
* This function has to setup any files the protocol want to
* appear in the kmem cgroup filesystem.
*/
- int (*init_cgroup)(struct cgroup *cgrp,
+ int (*init_cgroup)(struct mem_cgroup *memcg,
struct cgroup_subsys *ss);
- void (*destroy_cgroup)(struct cgroup *cgrp);
+ void (*destroy_cgroup)(struct mem_cgroup *memcg);
struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg);
#endif
};
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 48410ff..7df18bc 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -12,8 +12,8 @@ struct tcp_memcontrol {
};
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct cgroup *cgrp);
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void tcp_destroy_cgroup(struct mem_cgroup *memcg);
unsigned long long tcp_max_memory(const struct mem_cgroup *memcg);
void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx);
#endif /* _TCP_MEMCG_H */
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bef1142..704054d 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,29 +4640,22 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
- /*
- * Part of this would be better living in a separate allocation
- * function, leaving us with just the cgroup tree population work.
- * We, however, depend on state such as network's proto_list that
- * is only initialized after cgroup creation. I found the less
- * cumbersome way to deal with it to defer it all to populate time
- */
- return mem_cgroup_sockets_init(cont, ss);
+ return mem_cgroup_sockets_init(memcg, ss);
};
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
- mem_cgroup_sockets_destroy(cont);
+ mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -5034,7 +5027,7 @@ static void mem_cgroup_destroy(struct cgroup *cont)
{
struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- kmem_cgroup_destroy(cont);
+ kmem_cgroup_destroy(memcg);
mem_cgroup_put(memcg);
}
@@ -5042,7 +5035,8 @@ static void mem_cgroup_destroy(struct cgroup *cont)
static int mem_cgroup_populate(struct cgroup_subsys *ss,
struct cgroup *cont)
{
- return register_kmem_files(cont, ss);
+ struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
+ return register_kmem_files(memcg, ss);
}
#ifdef CONFIG_MMU
diff --git a/net/core/sock.c b/net/core/sock.c
index b2e14c0..878f744 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -140,7 +140,7 @@ static DEFINE_MUTEX(proto_list_mutex);
static LIST_HEAD(proto_list);
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
struct proto *proto;
int ret = 0;
@@ -148,7 +148,7 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
mutex_lock(&proto_list_mutex);
list_for_each_entry(proto, &proto_list, node) {
if (proto->init_cgroup) {
- ret = proto->init_cgroup(cgrp, ss);
+ ret = proto->init_cgroup(memcg, ss);
if (ret)
goto out;
}
@@ -159,19 +159,19 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
out:
list_for_each_entry_continue_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
return ret;
}
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
struct proto *proto;
mutex_lock(&proto_list_mutex);
list_for_each_entry_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
}
#endif
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 8f1753d..1517037 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -18,7 +18,7 @@ static void memcg_tcp_enter_memory_pressure(struct sock *sk)
}
EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
/*
* The root cgroup does not use res_counters, but rather,
@@ -28,7 +28,6 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
struct res_counter *res_parent = NULL;
struct cg_proto *cg_proto, *parent_cg;
struct tcp_memcontrol *tcp;
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct mem_cgroup *parent = parent_mem_cgroup(memcg);
struct net *net = current->nsproxy->net_ns;
@@ -61,9 +60,8 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
}
EXPORT_SYMBOL(tcp_init_cgroup);
-void tcp_destroy_cgroup(struct cgroup *cgrp)
+void tcp_destroy_cgroup(struct mem_cgroup *memcg)
{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct cg_proto *cg_proto;
struct tcp_memcontrol *tcp;
u64 val;
--
1.7.7.6
^ permalink raw reply related
* [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Johannes Weiner, Michal Hocko
In-Reply-To: <1334010994-23301-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The last man standing justifying the need for populate() is the
sock memcg initialization functions. Now that we are able to pass
a struct mem_cgroup instead of a struct cgroup to the socket
initialization, there is nothing that stops us from initializing
everything in create().
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
---
mm/memcontrol.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 704054d..02b01d2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,7 +4640,7 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return mem_cgroup_sockets_init(memcg, ss);
};
@@ -4650,7 +4650,7 @@ static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
@@ -5010,6 +5010,17 @@ mem_cgroup_create(struct cgroup *cont)
memcg->move_charge_at_immigrate = 0;
mutex_init(&memcg->thresholds_lock);
spin_lock_init(&memcg->move_lock);
+
+ error = memcg_init_kmem(memcg, &mem_cgroup_subsys);
+ if (error) {
+ /*
+ * We call put now because our (and parent's) refcnts
+ * are already in place. mem_cgroup_put() will internally
+ * call __mem_cgroup_free, so return directly
+ */
+ mem_cgroup_put(memcg);
+ return ERR_PTR(error);
+ }
return &memcg->css;
free_out:
__mem_cgroup_free(memcg);
@@ -5032,13 +5043,6 @@ static void mem_cgroup_destroy(struct cgroup *cont)
mem_cgroup_put(memcg);
}
-static int mem_cgroup_populate(struct cgroup_subsys *ss,
- struct cgroup *cont)
-{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- return register_kmem_files(memcg, ss);
-}
-
#ifdef CONFIG_MMU
/* Handlers for move charge at task migration. */
#define PRECHARGE_COUNT_AT_ONCE 256
@@ -5622,7 +5626,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
.create = mem_cgroup_create,
.pre_destroy = mem_cgroup_pre_destroy,
.destroy = mem_cgroup_destroy,
- .populate = mem_cgroup_populate,
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
--
1.7.7.6
^ permalink raw reply related
* Re: [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: Tejun Heo @ 2012-04-09 22:42 UTC (permalink / raw)
To: Glauber Costa
Cc: netdev, cgroups, Li Zefan, kamezawa.hiroyu, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-3-git-send-email-glommer@parallels.com>
On Mon, Apr 09, 2012 at 07:36:34PM -0300, Glauber Costa wrote:
> The last man standing justifying the need for populate() is the
> sock memcg initialization functions. Now that we are able to pass
> a struct mem_cgroup instead of a struct cgroup to the socket
> initialization, there is nothing that stops us from initializing
> everything in create().
>
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: Tejun Heo <tj@kernel.org>
> CC: Li Zefan <lizefan@huawei.com>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> CC: Johannes Weiner <hannes@cmpxchg.org>
> CC: Michal Hocko <mhocko@suse.cz>
Will apply once memcg maintainers ack.
Thanks.
--
tejun
^ permalink raw reply
* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
From: Will Drewry @ 2012-04-09 22:47 UTC (permalink / raw)
To: Ryan Ware, Markus Gutschke, Andrew Morton
Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
keescook, jmorris
In-Reply-To: <CBA89B80.3C770%ware@linux.intel.com>
On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>
> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>
>>No matter what you do, please leave the samples accessible somewhere.
>>They proved incredibly useful in figuring out how the API works. I am
>>sure, other developers are going to appreciate them as well.
>>
>>Alternatively, if you don't want to include the samples with the
>>kernel sources, figure out how you can include a sample in the
>>official manual page for prctl().
>>
>
> I second this! They are extremely useful.
>
> Ryan
In that case, would it make sense to put up a separate tools/testing
patch and leave samples where they lie? (I'd _love_ to keep this patch
series from acquiring another 1000 lines, but either way works :)
My current tester and harness lives here:
https://github.com/redpig/seccomp/blob/master/tests/
and the licensing can be sorted out prior to a patch mail.
thanks!
will
^ permalink raw reply
* Re: [PATCH 5/9] ipvs: use adaptive pause in master thread
From: Pablo Neira Ayuso @ 2012-04-09 23:08 UTC (permalink / raw)
To: Julian Anastasov
Cc: Simon Horman, lvs-devel, netdev, netfilter-devel, Wensong Zhang
In-Reply-To: <alpine.LFD.2.00.1204082221440.6964@ja.ssi.bg>
Hi Julian,
On Sun, Apr 08, 2012 at 11:12:53PM +0300, Julian Anastasov wrote:
>
> Hello,
>
> On Thu, 5 Apr 2012, Pablo Neira Ayuso wrote:
>
> > I think you can control when the kernel thread is woken up with a
> > counting semaphore. The counter of that semaphore will be initially
> > set to zero. Then, you can up() the semaphore once per new buffer
> > that you enqueue to the sender.
> >
> > feeder:
> > add message to sync buffer
> > if buffer full:
> > enqueue buffer to sender_thread
> > up(s)
> >
> > sender_thread:
> > while (1) {
> > down(s)
> > retrieve message from queue
> > send message
> > }
> >
> > It seems to me like the classical producer/consumer problem that you
> > can resolve with semaphores.
>
> May be it is possible to use up/down but we
> have to handle the kthread_should_stop check and also
> I prefer to reduce the wakeup events. So, I'm trying
> another solution which is appended just for review.
You can still use kthread_should_stop inside a wrapper function
that calls kthread_stop and up() the semaphore.
sync_stop:
kthread_stop(k)
up(s)
kthread_routine:
while(1) {
down(s)
if (kthread_should_stop(k))
break;
get sync msg
send sync msg
}
BTW, each up() does not necessarily mean one wakeup event. up() will
delivery only one wakeup event for one process that has been already
awaken.
> > Under congestion the situation is complicated. At some point you'll
> > end up dropping messages.
> >
> > You may want to increase the socket queue to delay the moment at which
> > we start dropping messages. You can expose the socke buffer length via
> > /proc interface I guess (not sure if you're already doing that or
> > suggesting to use the global socket buffer length).
>
> I'm still thinking if sndbuf value should be exported,
> currently users have to modify the global default/max value.
I think it's a good idea.
> But in below version I'm trying to handle the sndbuf overflow
> by blocking for write_space event. By this way we should work
> with any sndbuf configuration.
You seem to be defering the overrun problem by using a longer
intermediate queue than the socket buffer. Then, that queue can be
tuned by the user via sysctl. It may happen under heavy stress that
your intermediate queue gets full again, then you'll have to drop
packets at some point.
> > You also can define some mechanism to reduce the amount of events,
> > some state filtering so you only propagate important states.
> >
> > Some partially reliable protocol, so the backup can request messages
> > that got lost in a smart way would can also in handy. Basically, the
> > master only retransmits the current state, not the whole sequence of
> > messages (this is good under congestion, since you save messages).
> > I implement that in conntrackd, but that's more complex solution,
> > of course. I'd start with something simple.
>
> The patch "reduce sync rate with time thresholds"
> that follows the discussed one in the changeset has such
> purpose to reduce the events, in tests the sync traffic is
> reduced ~10 times. But it does not modify the current
> protocol, it adds a very limited logic for retransmissions.
Not directly related to this, but I'd prefer if any retransmission
support (or any new feature) gets added in follow-up patches. So we
can things separated in logic pieces. Thanks.
^ permalink raw reply
* linux-next: manual merge of the wireless-next tree with the net-next tree
From: Stephen Rothwell @ 2012-04-10 1:32 UTC (permalink / raw)
To: John W. Linville
Cc: linux-next, linux-kernel, David Miller, netdev,
Meenakshi Venkataraman, Wey-Yi Guy
[-- Attachment #1: Type: text/plain, Size: 1442 bytes --]
Hi John,
Today's linux-next merge of the wireless-next tree got a conflict in
drivers/net/wireless/iwlwifi/iwl-testmode.c between commit d33e152e1edd
("iwlwifi: Stop using NLA_PUT*()") from the net-next tree and commit
a42506eb27aa ("iwlwifi: move ucode_type from shared to op_mode") from the
wireless-next tree.
I fixed it up (see below) and can carry the fix as necessary.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/net/wireless/iwlwifi/iwl-testmode.c
index a54e20e,d65dac8..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@@ -609,10 -605,9 +612,10 @@@ static int iwl_testmode_driver(struct i
inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
}
- if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type) ||
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
++ if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 1:35 UTC (permalink / raw)
To: Tejun Heo
Cc: Glauber Costa, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko, Balbir Singh
In-Reply-To: <20120409174042.GA7522-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
(2012/04/10 2:40), Tejun Heo wrote:
> (cc'ing other memcg ppl just in case)
>
> Hello,
>
> I don't think the error handling is correct here.
>
> On Fri, Apr 06, 2012 at 08:04:10PM +0400, Glauber Costa wrote:
>> The last man standing justifying the need for populate() is the
>> sock memcg initialization functions. Now that we are able to pass
>> a struct mem_cgroup instead of a struct cgroup to the socket
>> initialization, there is nothing that stops us from initializing
>> everything in create().
>>
>> Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
>> CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
> ...
>> @@ -5010,7 +5010,9 @@ mem_cgroup_create(struct cgroup *cont)
>> memcg->move_charge_at_immigrate = 0;
>> mutex_init(&memcg->thresholds_lock);
>> spin_lock_init(&memcg->move_lock);
>> - return &memcg->css;
>> +
>> + if (!memcg_init_kmem(memcg, &mem_cgroup_subsys))
>> + return &memcg->css;
>> free_out:
>> __mem_cgroup_free(memcg);
>> return ERR_PTR(error);
>
> So, the control is just falling through free_out: on kmem init
> failure; however, there seem to be stuff which needs to be undone -
> hotcpu_notifier() registration, which BTW seems incorrect even on its
> own - unmounting and mounting again would probably make the same
> notifier registered multiple times corrupting notification chain, and
> ref inc on the parent.
>
ok, it should be fixed.
> It probably would be best to reorganize the function slightly such
> that, it's organized as...
>
> 1. alloc
> 2. init stuff w/o other side effects
> 3. make side effects
>
> and add kmemcg init at the end of the second step.
>
> Also, memcg maintainers, once the patches get updated and acked, I'd
> like to route them through cgroup tree so that I can kill ->populate
> there. cgroup/for-3.5 is stable branch which can be pulled into other
> trees including the memcg one. Would that be okay?
>
Hm, I'm okay with that but.....Michal ?
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 1:37 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko, Balbir Singh
In-Reply-To: <4F83218E.7060502-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 2:51), Glauber Costa wrote:
> On 04/09/2012 02:40 PM, Tejun Heo wrote:
>> which BTW seems incorrect even on its
>> own - unmounting and mounting again would probably make the same
>> notifier registered multiple times corrupting notification chain, and
>> ref inc on the parent.
>
>
> For the maintainers: Should I fix those in a new submission, or do you
> intend to do it yourselves?
>
> the refcnt dropping should probably be done in my patch, it is a new
> leak (sorry). The hotplug notifier, as tejun pointed, was already there.
>
> It seems simple enough to fix, so if you guys want, I can bundle it in
> a new submission.
>
Please make notifier fix patch against mm tree, as an independent one.
Thanks,
-Kame
^ permalink raw reply
* Kernel panic with sysfs adding group for pmu device
From: Brown, Aaron F @ 2012-04-10 2:05 UTC (permalink / raw)
To: netdev@vger.kernel.org
Hi all,
I'm getting a kernel panic on boot with the the net-next tree on a
number of test systems I work with. So far this appears on older Intel
Xeon server platforms that have an ESB based chipset with either an x86
or x86_64 kernel.
Here is the panic I am seeing:
---------------------------------
Starts to boots normally to ...
...
Trying to unpack rootfs image as initramfs...
debug: unmapping init memory f748b000..f77fe000
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c10d19a0>] internal_create_group+0xdc/0x138
*pde = 00000000
Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
Modules linked in:
Pid: 1, comm: swapper/0 Not tainted 3.4.0-rc1_net-next_igb_2107cad... #2
Intel /SE7525GP2
EIP: 0060:[<c10d19a0>] EFLAGS: 00010246 CPU: 0
EIP is at internal_create_group+0xdc/0x138
EAX: 00000001 EBX: f4fc0df8 ECX: 00000000 EDX: 00000000
ESI: 00000000 EDI: 00000000 EBP: f58fbf34 ESP: f58fbf14
DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
CR0: 8005003b CR2: 00000000 CR3: 014fc000 CR4: 000007d0
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
Process swapper/0 (pid: 1, ti=f58fa000 task=f58e9c60 task.ti=f58fa000)
Stack:
00000000 f4fc2238 00000000 c146b780 f4fc2238 00000001 c146b80c 00000000
f58fbf3c c10d1a19 f58fbf54 c1188d3f f4fc0df8 f4fc0df0 00000000 00000000
f58fbf90 c11893a1 c1188d81 00000000 00000000 f4fc0df0 f4fc0df8 c14e5f24
Call Trace:
[<c10d1a19>] sysfs_create_group+0xc/0xf
[<c1188d3f>] device_add_groups+0x21/0x4e
[<c11893a1>] device_add+0x2fa/0x4fb
[<c1188d81>] ? device_private_init+0x15/0x49
[<c1188da2>] ? device_private_init+0x36/0x49
[<c10605bb>] pmu_dev_alloc+0x75/0x8e
[<c14a8dbc>] perf_event_sysfs_init+0x3f/0x85
[<c1001159>] do_one_initcall+0x71/0x113
[<c14a8d7d>] ? utsname_sysctl_init+0x11/0x11
[<c149727c>] kernel_init+0xd8/0x161
[<c14971a4>] ? parse_early_options+0x21/0x21
[<c1339ef6>] kernel_thread_helper+0x6/0xd
Code: d7 66 85 c0 74 21 8b 4d e8 8b 14 b1 b9 02 00 00 00 0b 42 04 0f b7
c0 50 8b 45 e4 e8 01 e1 ff ff 89 c7 59 85 c0 75 0f 46 8b 55 e8 <8b> 04
b2 85 c0 75 a5 31 ff eb 27 8b 4d ec 8b 59 08 eb 0f 8b 08
EIP: [<c10d19a0>] internal_create_group+0xdc/0x138 SS:ESP 0068:f58fbf14
CR2: 0000000000000000
---[ end trace e93713a9d40cd06c ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
---------------------------------
I tried disabling DEBUG_PAGEALLOC as well as
different preempt settings, compiled as single proc, etc... The panic
continued, but modified "Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC" line
to represent the actual settings.
I ran a series of git bisects and found that the patch that introduced
the panics is:
-------------------------------------------
u1460:[0]/usr/src/kernels/net-next> git bisect good
641cc938815dfd09f8fa1ec72deb814f0938ac33 is first bad commit
commit 641cc938815dfd09f8fa1ec72deb814f0938ac33
Author: Jiri Olsa <jolsa@redhat.com>
Date: Thu Mar 15 20:09:14 2012 +0100
perf: Adding sysfs group format attribute for pmu device
Adding sysfs group 'format' attribute for pmu device that
contains a syntax description on how to construct raw events.
The event configuration is described in following
struct pefr_event_attr attributes:
config
config1
config2
Each sysfs attribute within the format attribute group,
describes mapping of name and bitfield definition within
one of above attributes.
eg:
"/sys/...<dev>/format/event" contains "config:0-7"
"/sys/...<dev>/format/umask" contains "config:8-15"
"/sys/...<dev>/format/usr" contains "config:16"
the attribute value syntax is:
line: config ':' bits
config: 'config' | 'config1' | 'config2"
bits: bits ',' bit_term | bit_term
bit_term: VALUE '-' VALUE | VALUE
Adding format attribute definitions for x86 cpu pmus.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Link:
http://lkml.kernel.org/n/tip-vhdk5y2hyype9j63prymty36@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
:040000 040000 6997376a7fa63ee143dd365babc373cb298148a4
1779179772124f413d1d1b18fdd6bb3bdd9713c0 M Documentation
:040000 040000 1bbb2bd82a0abee4e9f55c9ccbc0805d4d0040c4
a947cf4cfd048f98904e5fc59b67253258b6f5a3 M arch
:040000 040000 bd74f46a57eb846a2ee7e3d60813bb1c1af2d71a
d95d819d91a7049d3e7355488436c4305319ceac M include
u1460:[0]/usr/src/kernels/net-next_igb-queue>
------------------------------------------------------
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:37 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F7F1091.9040204@parallels.com>
(2012/04/07 0:49), Glauber Costa wrote:
> On 03/30/2012 05:44 AM, KAMEZAWA Hiroyuki wrote:
>> Maybe what we can do before lsf/mm summit will be this (avoid warning.)
>> This patch is onto linus's git tree. Patch description is updated.
>>
>> Thanks.
>> -Kame
>> ==
>> From 4ab80f84bbcb02a790342426c1de84aeb17fcbe9 Mon Sep 17 00:00:00 2001
>> From: KAMEZAWA Hiroyuki<kamezawa.hiroyu@jp.fujitsu.com>
>> Date: Thu, 29 Mar 2012 14:59:04 +0900
>> Subject: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
>>
>> tcp memcontrol starts accouting after res->limit is set. So, if a sockets
>> starts before setting res->limit, there are already used resource.
>> At setting res->limit, accounting starts. The resource will be uncharged
>> and make res_counter below 0 because they are not charged.
>> This causes warning.
>>
>
> Kame,
>
> Please test the following patch and see if it fixes your problems (I
> tested locally, and it triggers me no warnings running the test script
> you provided + an inbound scp -r copy of an iso directory from a remote
> machine)
>
> When you are reviewing, keep in mind that we're likely to have the same
> problems with slab jump labels - since the slab pages will outlive the
> cgroup as well, and it might be worthy to keep this in mind, and provide
> a central point for the jump labels to be set of on cgroup destruction.
>
Hm. What happens in following sequence ?
1. a memcg is created
2. put a task into the memcg, start tcp steam
3. set tcp memory limit
The resource used between 2 and 3 will cause the problem finally.
Then, Dave's request
==
You must either:
1) Integrate the socket's existing usage when the limit is set.
2) Avoid accounting completely for a socket that started before
the limit was set.
==
are not satisfied. So, we need to have a state per sockets, it's accounted
or not. I'll look into this problem again, today.
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH v3 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:42 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-2-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 7:36), Glauber Costa wrote:
> The only reason cgroup was used, was to be consistent with the populate()
> interface. Now that we're getting rid of it, not only we no longer need
> it, but we also *can't* call it this way.
>
> Since we will no longer rely on populate(), this will be called from
> create(). During create, the association between struct mem_cgroup
> and struct cgroup does not yet exist, since cgroup internals hasn't
> yet initialized its bookkeeping. This means we would not be able
> to draw the memcg pointer from the cgroup pointer in these
> functions, which is highly undesirable.
>
> Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
> CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
> CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
^ permalink raw reply
* Re: [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:44 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-3-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 7:36), Glauber Costa wrote:
> The last man standing justifying the need for populate() is the
> sock memcg initialization functions. Now that we are able to pass
> a struct mem_cgroup instead of a struct cgroup to the socket
> initialization, there is nothing that stops us from initializing
> everything in create().
>
> Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
> CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
> CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: Glauber Costa @ 2012-04-10 2:51 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F839CF1.5050104@jp.fujitsu.com>
On 04/09/2012 11:37 PM, KAMEZAWA Hiroyuki wrote:
> Hm. What happens in following sequence ?
>
> 1. a memcg is created
> 2. put a task into the memcg, start tcp steam
> 3. set tcp memory limit
>
> The resource used between 2 and 3 will cause the problem finally.
I don't get it. if a task is in memcg, but no limit is set,
that socket will be assigned null memcg, and will stay like that
forever. Only new sockets will have the new memcg pointer.
And previously, we could have the memcg pointer alive, but the jump
labels to be disabled. With the patch I posted, this can't happen
anymore, since the jump labels are guaranteed to live throughout the
whole socket life.
> Then, Dave's request
> ==
> You must either:
>
> 1) Integrate the socket's existing usage when the limit is set.
>
> 2) Avoid accounting completely for a socket that started before
> the limit was set.
> ==
> are not satisfied. So, we need to have a state per sockets, it's accounted
> or not. I'll look into this problem again, today.
>
Of course they are.
Every socket created before we set the limit is not accounted.
This is 2) that Dave mentioned, and it was *always* this way.
The problem here was the opposite: You could disable the jump labels
with sockets still in flight, because we were disabling it based on
the limit being set back to unlimited.
What this patch does, is defer that until the last socket limited dies.
^ permalink raw reply
* [PATCH 0/2] adding tracepoints to vhost
From: Jason Wang @ 2012-04-10 2:58 UTC (permalink / raw)
To: netdev, virtualization, linux-kernel, kvm, mst
To help in vhost analyzing, the following series adding basic tracepoints to
vhost. Operations of both virtqueues and vhost works were traced in current
implementation, net code were untouched. A top-like satistics displaying script
were introduced to help the troubleshooting.
TODO:
- net specific tracepoints?
---
Jason Wang (2):
vhost: basic tracepoints
tools: virtio: add a top-like utility for displaying vhost satistics
drivers/vhost/trace.h | 153 ++++++++++++++++++++
drivers/vhost/vhost.c | 17 ++
tools/virtio/vhost_stat | 360 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 528 insertions(+), 2 deletions(-)
create mode 100644 drivers/vhost/trace.h
create mode 100755 tools/virtio/vhost_stat
--
Jason Wang
^ permalink raw reply
* [PATCH 1/2] vhost: basic tracepoints
From: Jason Wang @ 2012-04-10 2:58 UTC (permalink / raw)
To: netdev, virtualization, linux-kernel, kvm, mst
In-Reply-To: <20120410025327.49693.93562.stgit@amd-6168-8-1.englab.nay.redhat.com>
To help for the performance optimizations and debugging, this patch tracepoints
for vhost. Pay attention that the tracepoints are only for vhost, net code are
not touched.
Two kinds of activities were traced: virtio and vhost work.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/trace.h | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/vhost/vhost.c | 17 +++++
2 files changed, 168 insertions(+), 2 deletions(-)
create mode 100644 drivers/vhost/trace.h
diff --git a/drivers/vhost/trace.h b/drivers/vhost/trace.h
new file mode 100644
index 0000000..0423899
--- /dev/null
+++ b/drivers/vhost/trace.h
@@ -0,0 +1,153 @@
+#if !defined(_TRACE_VHOST_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_VHOST_H
+
+#include <linux/tracepoint.h>
+#include "vhost.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM vhost
+
+/*
+ * Tracepoint for updating used flag.
+ */
+TRACE_EVENT(vhost_virtio_update_used_flags,
+ TP_PROTO(struct vhost_virtqueue *vq),
+ TP_ARGS(vq),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ __field(u16, used_flags)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ __entry->used_flags = vq->used_flags;
+ ),
+
+ TP_printk("vhost update used flag %x to vq %p notify %s",
+ __entry->used_flags, __entry->vq,
+ (__entry->used_flags & VRING_USED_F_NO_NOTIFY) ?
+ "disabled" : "enabled")
+);
+
+/*
+ * Tracepoint for updating avail event.
+ */
+TRACE_EVENT(vhost_virtio_update_avail_event,
+ TP_PROTO(struct vhost_virtqueue *vq),
+ TP_ARGS(vq),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ __field(u16, avail_idx)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ __entry->avail_idx = vq->avail_idx;
+ ),
+
+ TP_printk("vhost update avail idx %u(%u) for vq %p",
+ __entry->avail_idx, __entry->avail_idx %
+ __entry->vq->num, __entry->vq)
+);
+
+/*
+ * Tracepoint for processing descriptor.
+ */
+TRACE_EVENT(vhost_virtio_get_vq_desc,
+ TP_PROTO(struct vhost_virtqueue *vq, unsigned int index,
+ unsigned out, unsigned int in),
+ TP_ARGS(vq, index, out, in),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ __field(unsigned int, head)
+ __field(unsigned int, out)
+ __field(unsigned int, in)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ __entry->head = index;
+ __entry->out = out;
+ __entry->in = in;
+ ),
+
+ TP_printk("vhost get vq %p head %u out %u in %u",
+ __entry->vq, __entry->head, __entry->out, __entry->in)
+
+);
+
+/*
+ * Tracepoint for signal guest.
+ */
+TRACE_EVENT(vhost_virtio_signal,
+ TP_PROTO(struct vhost_virtqueue *vq),
+ TP_ARGS(vq),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ ),
+
+ TP_printk("vhost signal vq %p", __entry->vq)
+);
+
+DECLARE_EVENT_CLASS(vhost_work_template,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_dev *, dev)
+ __field(struct vhost_work *, work)
+ __field(void *, function)
+ ),
+
+ TP_fast_assign(
+ __entry->dev = dev;
+ __entry->work = work;
+ __entry->function = work->fn;
+ ),
+
+ TP_printk("%pf for work %p dev %p",
+ __entry->function, __entry->work, __entry->dev)
+);
+
+DEFINE_EVENT(vhost_work_template, vhost_work_queue_wakeup,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_work_queue_coalesce,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_poll_start,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_poll_stop,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_work_execute_start,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_work_execute_end,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+#endif /* _TRACE_VHOST_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/vhost
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c14c42b..23f8d85 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -31,6 +31,8 @@
#include <linux/if_arp.h>
#include "vhost.h"
+#define CREATE_TRACE_POINTS
+#include "trace.h"
enum {
VHOST_MEMORY_MAX_NREGIONS = 64,
@@ -50,6 +52,7 @@ static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
poll = container_of(pt, struct vhost_poll, table);
poll->wqh = wqh;
add_wait_queue(wqh, &poll->wait);
+ trace_vhost_poll_start(NULL, &poll->work);
}
static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync,
@@ -101,6 +104,7 @@ void vhost_poll_start(struct vhost_poll *poll, struct file *file)
void vhost_poll_stop(struct vhost_poll *poll)
{
remove_wait_queue(poll->wqh, &poll->wait);
+ trace_vhost_poll_stop(NULL, &poll->work);
}
static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
@@ -147,7 +151,9 @@ static inline void vhost_work_queue(struct vhost_dev *dev,
list_add_tail(&work->node, &dev->work_list);
work->queue_seq++;
wake_up_process(dev->worker);
- }
+ trace_vhost_work_queue_wakeup(dev, work);
+ } else
+ trace_vhost_work_queue_coalesce(dev, work);
spin_unlock_irqrestore(&dev->work_lock, flags);
}
@@ -221,7 +227,9 @@ static int vhost_worker(void *data)
if (work) {
__set_current_state(TASK_RUNNING);
+ trace_vhost_work_execute_start(dev, work);
work->fn(work);
+ trace_vhost_work_execute_end(dev, work);
} else
schedule();
@@ -1011,6 +1019,7 @@ static int vhost_update_used_flags(struct vhost_virtqueue *vq)
if (vq->log_ctx)
eventfd_signal(vq->log_ctx, 1);
}
+ trace_vhost_virtio_update_used_flags(vq);
return 0;
}
@@ -1030,6 +1039,7 @@ static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
if (vq->log_ctx)
eventfd_signal(vq->log_ctx, 1);
}
+ trace_vhost_virtio_update_avail_event(vq);
return 0;
}
@@ -1319,6 +1329,7 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
/* Assume notifications from guest are disabled at this point,
* if they aren't we would need to update avail_event index. */
BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY));
+ trace_vhost_virtio_get_vq_desc(vq, head, *out_num, *in_num);
return head;
}
@@ -1485,8 +1496,10 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
{
/* Signal the Guest tell them we used something up. */
- if (vq->call_ctx && vhost_notify(dev, vq))
+ if (vq->call_ctx && vhost_notify(dev, vq)) {
eventfd_signal(vq->call_ctx, 1);
+ trace_vhost_virtio_signal(vq);
+ }
}
/* And here's the combo meal deal. Supersize me! */
^ permalink raw reply related
* [PATCH 2/2] tools: virtio: add a top-like utility for displaying vhost satistics
From: Jason Wang @ 2012-04-10 2:58 UTC (permalink / raw)
To: netdev, virtualization, linux-kernel, kvm, mst
In-Reply-To: <20120410025327.49693.93562.stgit@amd-6168-8-1.englab.nay.redhat.com>
This patch adds simple python to display vhost satistics of vhost, the codes
were based on kvm_stat script from qemu. As work function has been recored,
filters could be used to distinguish which kinds of work are being executed or
queued:
vhost statistics
vhost_virtio_get_vq_desc 1460997 219682
vhost_work_execute_start 101248 12842
vhost_work_execute_end 101247 12842
vhost_work_queue_wakeup 101263 12841
vhost_virtio_signal 68452 8659
vhost_work_queue_wakeup(rx_net) 51797 6584
vhost_work_execute_start(rx_net) 51795 6584
vhost_work_queue_coalesce 35737 6571
vhost_work_queue_coalesce(rx_net) 35709 6566
vhost_virtio_update_avail_event 49512 6271
vhost_work_execute_start(tx_kick) 49429 6254
vhost_work_queue_wakeup(tx_kick) 49442 6252
vhost_work_queue_coalesce(tx_kick) 28 5
vhost_work_execute_start(rx_kick) 22 3
vhost_work_queue_wakeup(rx_kick) 22 3
vhost_poll_start 4 0
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
tools/virtio/vhost_stat | 360 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 360 insertions(+), 0 deletions(-)
create mode 100755 tools/virtio/vhost_stat
diff --git a/tools/virtio/vhost_stat b/tools/virtio/vhost_stat
new file mode 100755
index 0000000..b730f3b
--- /dev/null
+++ b/tools/virtio/vhost_stat
@@ -0,0 +1,360 @@
+#!/usr/bin/python
+#
+# top-like utility for displaying vhost statistics
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Modified from kvm_stat from qemu
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+
+import curses
+import sys, os, time, optparse
+
+work_types = {
+ "handle_rx_kick" : "rx_kick",
+ "handle_tx_kick" : "tx_kick",
+ "handle_rx_net" : "rx_net",
+ "handle_tx_net" : "tx_net",
+ "vhost_attach_cgroups_work": "cg_attach"
+ }
+
+addr = {}
+
+kallsyms = file("/proc/kallsyms").readlines()
+for kallsym in kallsyms:
+ entry = kallsym.split()
+ if entry[2] in work_types.keys():
+ addr["0x%s" % entry[0]] = work_types[entry[2]]
+
+filters = {
+ 'vhost_work_queue_wakeup': ('function', addr),
+ 'vhost_work_queue_coalesce' : ('function', addr),
+ 'vhost_work_execute_start' : ('function', addr),
+ 'vhost_poll_start' : ('function', addr),
+ 'vhost_poll_stop' : ('function', addr),
+}
+
+def invert(d):
+ return dict((x[1], x[0]) for x in d.iteritems())
+
+for f in filters:
+ filters[f] = (filters[f][0], invert(filters[f][1]))
+
+import ctypes, struct, array
+
+libc = ctypes.CDLL('libc.so.6')
+syscall = libc.syscall
+class perf_event_attr(ctypes.Structure):
+ _fields_ = [('type', ctypes.c_uint32),
+ ('size', ctypes.c_uint32),
+ ('config', ctypes.c_uint64),
+ ('sample_freq', ctypes.c_uint64),
+ ('sample_type', ctypes.c_uint64),
+ ('read_format', ctypes.c_uint64),
+ ('flags', ctypes.c_uint64),
+ ('wakeup_events', ctypes.c_uint32),
+ ('bp_type', ctypes.c_uint32),
+ ('bp_addr', ctypes.c_uint64),
+ ('bp_len', ctypes.c_uint64),
+ ]
+def _perf_event_open(attr, pid, cpu, group_fd, flags):
+ return syscall(298, ctypes.pointer(attr), ctypes.c_int(pid),
+ ctypes.c_int(cpu), ctypes.c_int(group_fd),
+ ctypes.c_long(flags))
+
+PERF_TYPE_HARDWARE = 0
+PERF_TYPE_SOFTWARE = 1
+PERF_TYPE_TRACEPOINT = 2
+PERF_TYPE_HW_CACHE = 3
+PERF_TYPE_RAW = 4
+PERF_TYPE_BREAKPOINT = 5
+
+PERF_SAMPLE_IP = 1 << 0
+PERF_SAMPLE_TID = 1 << 1
+PERF_SAMPLE_TIME = 1 << 2
+PERF_SAMPLE_ADDR = 1 << 3
+PERF_SAMPLE_READ = 1 << 4
+PERF_SAMPLE_CALLCHAIN = 1 << 5
+PERF_SAMPLE_ID = 1 << 6
+PERF_SAMPLE_CPU = 1 << 7
+PERF_SAMPLE_PERIOD = 1 << 8
+PERF_SAMPLE_STREAM_ID = 1 << 9
+PERF_SAMPLE_RAW = 1 << 10
+
+PERF_FORMAT_TOTAL_TIME_ENABLED = 1 << 0
+PERF_FORMAT_TOTAL_TIME_RUNNING = 1 << 1
+PERF_FORMAT_ID = 1 << 2
+PERF_FORMAT_GROUP = 1 << 3
+
+import re
+
+sys_tracing = '/sys/kernel/debug/tracing'
+
+class Group(object):
+ def __init__(self, cpu):
+ self.events = []
+ self.group_leader = None
+ self.cpu = cpu
+ def add_event(self, name, event_set, tracepoint, filter = None):
+ self.events.append(Event(group = self,
+ name = name, event_set = event_set,
+ tracepoint = tracepoint, filter = filter))
+ if len(self.events) == 1:
+ self.file = os.fdopen(self.events[0].fd)
+ def read(self):
+ bytes = 8 * (1 + len(self.events))
+ fmt = 'xxxxxxxx' + 'q' * len(self.events)
+ return dict(zip([event.name for event in self.events],
+ struct.unpack(fmt, self.file.read(bytes))))
+
+class Event(object):
+ def __init__(self, group, name, event_set, tracepoint, filter = None):
+ self.name = name
+ attr = perf_event_attr()
+ attr.type = PERF_TYPE_TRACEPOINT
+ attr.size = ctypes.sizeof(attr)
+ id_path = os.path.join(sys_tracing, 'events', event_set,
+ tracepoint, 'id')
+ id = int(file(id_path).read())
+ attr.config = id
+ attr.sample_type = (PERF_SAMPLE_RAW
+ | PERF_SAMPLE_TIME
+ | PERF_SAMPLE_CPU)
+ attr.sample_period = 1
+ attr.read_format = PERF_FORMAT_GROUP
+ group_leader = -1
+ if group.events:
+ group_leader = group.events[0].fd
+ fd = _perf_event_open(attr, -1, group.cpu, group_leader, 0)
+ if fd == -1:
+ raise Exception('perf_event_open failed')
+ if filter:
+ import fcntl
+ fcntl.ioctl(fd, 0x40082406, filter)
+ self.fd = fd
+ def enable(self):
+ import fcntl
+ fcntl.ioctl(self.fd, 0x00002400, 0)
+ def disable(self):
+ import fcntl
+ fcntl.ioctl(self.fd, 0x00002401, 0)
+
+class TracepointProvider(object):
+ def __init__(self):
+ path = os.path.join(sys_tracing, 'events', 'vhost')
+ fields = [f
+ for f in os.listdir(path)
+ if os.path.isdir(os.path.join(path, f))]
+ extra = []
+ for f in fields:
+ if f in filters:
+ subfield, values = filters[f]
+ for name, number in values.iteritems():
+ # kvm_exit(MMIO)
+ extra.append(f + '(' + name + ')')
+ fields += extra
+ self._setup(fields)
+ self.select(fields)
+ def fields(self):
+ return self._fields
+ def _setup(self, _fields):
+ self._fields = _fields
+ cpure = r'cpu([0-9]+)'
+ self.cpus = [int(re.match(cpure, x).group(1))
+ for x in os.listdir('/sys/devices/system/cpu')
+ if re.match(cpure, x)]
+ import resource
+ nfiles = len(self.cpus) * 1000
+ resource.setrlimit(resource.RLIMIT_NOFILE, (nfiles, nfiles))
+ events = []
+ self.group_leaders = []
+ for cpu in self.cpus:
+ group = Group(cpu)
+ for name in _fields:
+ tracepoint = name
+ filter = None
+ # for field like kvm_exit(MMIO)
+ m = re.match(r'(.*)\((.*)\)', name)
+ if m:
+ tracepoint, sub = m.groups()
+ filter = '%s==%s\0' % (filters[tracepoint][0],
+ filters[tracepoint][1][sub])
+ event = group.add_event(name, event_set = 'vhost',
+ tracepoint = tracepoint,
+ filter = filter)
+ self.group_leaders.append(group)
+ def select(self, fields):
+ for group in self.group_leaders:
+ for event in group.events:
+ if event.name in fields:
+ event.enable()
+ else:
+ event.disable()
+ def read(self):
+ from collections import defaultdict
+ ret = defaultdict(int)
+ for group in self.group_leaders:
+ for name, val in group.read().iteritems():
+ ret[name] += val
+ return ret
+
+class Stats:
+ def __init__(self, provider, fields = None):
+ self.provider = provider
+ self.fields_filter = fields
+ self._update()
+ def _update(self):
+ def wanted(key):
+ import re
+ if not self.fields_filter:
+ return True
+ return re.match(self.fields_filter, key) is not None
+ self.values = dict([(key, None)
+ for key in provider.fields()
+ if wanted(key)])
+ self.provider.select(self.values.keys())
+ def set_fields_filter(self, fields_filter):
+ self.fields_filter = fields_filter
+ self._update()
+ def get(self):
+ new = self.provider.read()
+ for key in self.provider.fields():
+ oldval = self.values.get(key, (0, 0))
+ newval = new[key]
+ newdelta = None
+ if oldval is not None:
+ newdelta = newval - oldval[0]
+ self.values[key] = (newval, newdelta)
+ return self.values
+
+if not os.access('/sys/kernel/debug', os.F_OK):
+ print 'Please enable CONFIG_DEBUG_FS in your kernel'
+ sys.exit(1)
+if not os.access('/sys/module/vhost_net', os.F_OK):
+ print 'Please make sure vhost module are loaded'
+ sys.exit(1)
+
+label_width = 40
+number_width = 10
+
+def tui(screen, stats):
+ curses.use_default_colors()
+ curses.noecho()
+ drilldown = False
+ fields_filter = stats.fields_filter
+ def update_drilldown():
+ if not fields_filter:
+ if drilldown:
+ stats.set_fields_filter(None)
+ else:
+ stats.set_fields_filter(r'^[^\(]*$')
+ update_drilldown()
+ def refresh(sleeptime):
+ screen.erase()
+ screen.addstr(0, 0, 'vhost statistics')
+ row = 2
+ s = stats.get()
+ def sortkey(x):
+ if s[x][1]:
+ return (-s[x][1], -s[x][0])
+ else:
+ return (0, -s[x][0])
+ for key in sorted(s.keys(), key = sortkey):
+ if row >= screen.getmaxyx()[0]:
+ break
+ values = s[key]
+ if not values[0] and not values[1]:
+ break
+ col = 1
+ screen.addstr(row, col, key)
+ col += label_width
+ screen.addstr(row, col, '%10d' % (values[0],))
+ col += number_width
+ if values[1] is not None:
+ screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
+ row += 1
+ screen.refresh()
+
+ sleeptime = 0.25
+ while True:
+ refresh(sleeptime)
+ curses.halfdelay(int(sleeptime * 10))
+ sleeptime = 3
+ try:
+ c = screen.getkey()
+ if c == 'x':
+ drilldown = not drilldown
+ update_drilldown()
+ if c == 'q':
+ break
+ except KeyboardInterrupt:
+ break
+ except curses.error:
+ continue
+
+def batch(stats):
+ s = stats.get()
+ time.sleep(1)
+ s = stats.get()
+ for key in sorted(s.keys()):
+ values = s[key]
+ print '%-22s%10d%10d' % (key, values[0], values[1])
+
+def log(stats):
+ keys = sorted(stats.get().iterkeys())
+ def banner():
+ for k in keys:
+ print '%10s' % k[0:9],
+ print
+ def statline():
+ s = stats.get()
+ for k in keys:
+ print ' %9d' % s[k][1],
+ print
+ line = 0
+ banner_repeat = 20
+ while True:
+ time.sleep(1)
+ if line % banner_repeat == 0:
+ banner()
+ statline()
+ line += 1
+
+options = optparse.OptionParser()
+options.add_option('-1', '--once', '--batch',
+ action = 'store_true',
+ default = False,
+ dest = 'once',
+ help = 'run in batch mode for one second',
+ )
+options.add_option('-l', '--log',
+ action = 'store_true',
+ default = False,
+ dest = 'log',
+ help = 'run in logging mode (like vmstat)',
+ )
+options.add_option('-f', '--fields',
+ action = 'store',
+ default = None,
+ dest = 'fields',
+ help = 'fields to display (regex)',
+ )
+(options, args) = options.parse_args(sys.argv)
+
+try:
+ provider = TracepointProvider()
+except:
+ print "Could not initialize tracepoint"
+ sys.exit(1)
+
+stats = Stats(provider, fields = options.fields)
+
+if options.log:
+ log(stats)
+elif not options.once:
+ import curses.wrapper
+ curses.wrapper(tui, stats)
+else:
+ batch(stats)
^ permalink raw reply related
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: Glauber Costa @ 2012-04-10 3:01 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F83A022.1000701@parallels.com>
On 04/09/2012 11:51 PM, Glauber Costa wrote:
> On 04/09/2012 11:37 PM, KAMEZAWA Hiroyuki wrote:
>> Hm. What happens in following sequence ?
>>
>> 1. a memcg is created
>> 2. put a task into the memcg, start tcp steam
>> 3. set tcp memory limit
>>
>> The resource used between 2 and 3 will cause the problem finally.
>
> I don't get it. if a task is in memcg, but no limit is set,
> that socket will be assigned null memcg, and will stay like that
> forever. Only new sockets will have the new memcg pointer.
>
> And previously, we could have the memcg pointer alive, but the jump
> labels to be disabled. With the patch I posted, this can't happen
> anymore, since the jump labels are guaranteed to live throughout the
> whole socket life.
>
>> Then, Dave's request
>> ==
>> You must either:
>>
>> 1) Integrate the socket's existing usage when the limit is set.
>>
>> 2) Avoid accounting completely for a socket that started before
>> the limit was set.
>> ==
>> are not satisfied. So, we need to have a state per sockets, it's accounted
>> or not. I'll look into this problem again, today.
>>
>
> Of course they are.
>
> Every socket created before we set the limit is not accounted.
> This is 2) that Dave mentioned, and it was *always* this way.
>
> The problem here was the opposite: You could disable the jump labels
> with sockets still in flight, because we were disabling it based on
> the limit being set back to unlimited.
>
> What this patch does, is defer that until the last socket limited dies.
>
Okay, there is an additional thing to be considered here:
Due to the nature of how jump label works, once they are enabled for one
of the cgroups, they will be enabled for all of them. So the patch I
sent may still break in some scenarios because of the way we record that
the limit was set.
However, if my theory behind what is causing the problem is correct,
this patch should fix the issue for you. Let me know if it does, and
I'll work on the final solution.
^ 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