* Re: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Jesper Dangaard Brouer @ 2013-03-14 9:18 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: Eric Dumazet, netdev, yoshfuji
In-Reply-To: <20130314072839.GD4129@order.stressinduktion.org>
On Thu, 2013-03-14 at 08:28 +0100, Hannes Frederic Sowa wrote:
> On Thu, Mar 14, 2013 at 08:23:41AM +0100, Hannes Frederic Sowa wrote:
> > On Thu, Mar 14, 2013 at 08:10:40AM +0100, Jesper Dangaard Brouer wrote:
> > > On Thu, 2013-03-14 at 02:37 +0100, Hannes Frederic Sowa wrote:
> > >
> > > > [PATCH net] inet: limit length of fragment queue hash table bucket lists
> > > >
> > > > This patch introduces a constant limit of the fragment queue hash
> > > > table bucket list lengths. Currently the limit 128 is choosen somewhat
> > > > arbitrary and just ensures that we can fill up the fragment cache with
> > > > empty packets up to the default ip_frag_high_thresh limits. It should
> > > > just protect from list iteration eating considerable amounts of cpu.
> > > >
> > > > If we reach the maximum length in one hash bucket a warning is printed.
> > > > This is implemented on the caller side of inet_frag_find to distinguish
> > > > between the different users of inet_fragment.c.
> > >
> > > I like the idea of having a safe guard on the fragment queue hash table
> > > bucket list lengths. But I'm considering another cleanup/evictor
> > > strategy, where we drop the LRU list, and do frag eviction on a hash
> > > bucket level (which will be more cache optimal). This strategy would
> > > also involve a list length limit.
> >
> > I would try to get a simple guard into v3.9. In 3.9 the hashing of the key
> > of ipv6 fragments changed in such a way that an attacker could generate
> > fragments which would end up in just one hash chain, thus eating a lot
> > of cpu time because of list traversal. Later on, when you post your
> > patches we could simply revert/update this safeguard to your version.
>
> I just wanted to mention that if you plan to target v3.9 with some patches we
> could simply drop this patch.
I will start working on this as soon as Netfilter Workshop is over and I
have recovered from organizing this event. DaveM told me I needed to
finish my frag patches first, before I could implement all the other
cool ideas we have come up with during the workshop ;-)
But I don't know if my frag changes can make v3.9, maybe v3.10 is more
realistic? In which case we should use your patch to close this problem
on v3.9 IMHO.
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* [PATCH] netfilter: nf_conntrack: Batch cleanup
From: Vladimir Davydov @ 2013-03-14 9:40 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: netfilter-devel, netfilter, coreteam, netdev, linux-kernel, devel,
Patrick McHardy, David S. Miller, Eric W. Biederman
The patch introduces nf_conntrack_cleanup_net_list(), which cleanups
nf_conntrack for a list of netns and calls synchronize_net() only once
for them all. This should reduce netns destruction time.
--
I've measured cleanup time for 1k dummy net ns. Here are the results:
<without the patch>
# modprobe nf_conntrack
# time modprobe -r nf_conntrack
real 0m10.337s
user 0m0.000s
sys 0m0.376s
<with the patch>
# modprobe nf_conntrack
# time modprobe -r nf_conntrack
real 0m5.661s
user 0m0.000s
sys 0m0.216s
Signed-off-by: Vladimir Davydov <vdavydov@parallels.com>
Cc: Patrick McHardy <kaber@trash.net>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
---
include/net/netfilter/nf_conntrack_core.h | 1 +
net/netfilter/nf_conntrack_core.c | 46 ++++++++++++++++++++---------
net/netfilter/nf_conntrack_standalone.c | 16 ++++++----
3 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 930275f..fb2b623 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -27,6 +27,7 @@ extern unsigned int nf_conntrack_in(struct net *net,
extern int nf_conntrack_init_net(struct net *net);
extern void nf_conntrack_cleanup_net(struct net *net);
+extern void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list);
extern int nf_conntrack_proto_pernet_init(struct net *net);
extern void nf_conntrack_proto_pernet_fini(struct net *net);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index c8e001a..09c02ef 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1364,30 +1364,48 @@ void nf_conntrack_cleanup_end(void)
*/
void nf_conntrack_cleanup_net(struct net *net)
{
+ LIST_HEAD(single);
+
+ list_add(&net->exit_list, &single);
+ nf_conntrack_cleanup_net_list(&single);
+}
+
+void nf_conntrack_cleanup_net_list(struct list_head *net_exit_list)
+{
+ int busy;
+ struct net *net;
+
/*
* This makes sure all current packets have passed through
* netfilter framework. Roll on, two-stage module
* delete...
*/
synchronize_net();
- i_see_dead_people:
- nf_ct_iterate_cleanup(net, kill_all, NULL);
- nf_ct_release_dying_list(net);
- if (atomic_read(&net->ct.count) != 0) {
+i_see_dead_people:
+ busy = 0;
+ list_for_each_entry(net, net_exit_list, exit_list) {
+ nf_ct_iterate_cleanup(net, kill_all, NULL);
+ nf_ct_release_dying_list(net);
+ if (atomic_read(&net->ct.count) != 0)
+ busy = 1;
+ }
+ if (busy) {
schedule();
goto i_see_dead_people;
}
- nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
- nf_conntrack_proto_pernet_fini(net);
- nf_conntrack_helper_pernet_fini(net);
- nf_conntrack_ecache_pernet_fini(net);
- nf_conntrack_tstamp_pernet_fini(net);
- nf_conntrack_acct_pernet_fini(net);
- nf_conntrack_expect_pernet_fini(net);
- kmem_cache_destroy(net->ct.nf_conntrack_cachep);
- kfree(net->ct.slabname);
- free_percpu(net->ct.stat);
+ list_for_each_entry(net, net_exit_list, exit_list) {
+ nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
+ nf_conntrack_proto_pernet_fini(net);
+ nf_conntrack_helper_pernet_fini(net);
+ nf_conntrack_ecache_pernet_fini(net);
+ nf_conntrack_tstamp_pernet_fini(net);
+ nf_conntrack_acct_pernet_fini(net);
+ nf_conntrack_expect_pernet_fini(net);
+ kmem_cache_destroy(net->ct.nf_conntrack_cachep);
+ kfree(net->ct.slabname);
+ free_percpu(net->ct.stat);
+ }
}
void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 6bcce40..6c69fbd 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -545,16 +545,20 @@ out_init:
return ret;
}
-static void nf_conntrack_pernet_exit(struct net *net)
+static void nf_conntrack_pernet_exit(struct list_head *net_exit_list)
{
- nf_conntrack_standalone_fini_sysctl(net);
- nf_conntrack_standalone_fini_proc(net);
- nf_conntrack_cleanup_net(net);
+ struct net *net;
+
+ list_for_each_entry(net, net_exit_list, exit_list) {
+ nf_conntrack_standalone_fini_sysctl(net);
+ nf_conntrack_standalone_fini_proc(net);
+ }
+ nf_conntrack_cleanup_net_list(net_exit_list);
}
static struct pernet_operations nf_conntrack_net_ops = {
- .init = nf_conntrack_pernet_init,
- .exit = nf_conntrack_pernet_exit,
+ .init = nf_conntrack_pernet_init,
+ .exit_batch = nf_conntrack_pernet_exit,
};
static int __init nf_conntrack_standalone_init(void)
--
1.7.1
^ permalink raw reply related
* RE: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: David Laight @ 2013-03-14 9:47 UTC (permalink / raw)
To: Hannes Frederic Sowa, Stephen Hemminger
Cc: Eric Dumazet, netdev, yoshfuji, brouer
In-Reply-To: <20130314071408.GB4129@order.stressinduktion.org>
> On Wed, Mar 13, 2013 at 09:36:52PM -0700, Stephen Hemminger wrote:
> > > +#define INET_FRAG_FIND_CHECK(val) \
> > > + ({ \
> > > + static const char ___mem[] = \
> > > + KERN_ERR pr_fmt( \
> > > + "inet_frag_find: No memory left." \
> > > + " Dropping fragment.\n"); \
> > > + static const char ___limit[] = \
> > > + KERN_WARNING pr_fmt( \
> > > + "inet_frag_find: Fragment hash bucket" \
> > > + " list length grew above limit " \
> > > + __stringify(INETFRAGS_MAXDEPTH) \
> > > + ". Dropping fragment.\n"); \
> > > + bool ___b = true; \
> > > + if (IS_ERR_OR_NULL(val)) { \
> > > + ___b = false; \
> > > + if (PTR_ERR(val) == -ENOBUFS) \
> > > + LIMIT_NETDEBUG(___limit); \
> > > + else \
> > > + LIMIT_NETDEBUG(___mem); \
> > > + } \
> > > + ___b; \
> > > + })
> > > +
> >
> > Big macros suck, write it as an inline function or better yet a real function.
>
> I switched to the macro to have string expansion with pr_fmt. So it is visible
> from the dmesg if IPv4, IPv6 or IPv6-nf did generate the message. This could
> be done with a function, too, but would require a bit more string handling.
I'd guess it would be best to have the IS_ERR_OR_NULL() inline calling a
real function on error.
I'd also have thought that INETFRAGS_MAXDEPTH should be run-time tunable.
David
^ permalink raw reply
* Re: [PATCH v3 net-next 1/1] drivers: net: davinci_cpdma: acknowledge interrupt properly
From: Mugunthan V N @ 2013-03-14 10:21 UTC (permalink / raw)
To: Mark Jackson; +Cc: netdev, davem, linux-arm-kernel, linux-omap
In-Reply-To: <51404838.2040008@mimc.co.uk>
On 3/13/2013 3:04 PM, Mark Jackson wrote:
> On 18/02/13 08:19, Mugunthan V N wrote:
>> >CPDMA interrupts are not properly acknowledged which leads to interrupt
>> >storm, only cpdma interrupt 0 is acknowledged in Davinci CPDMA driver.
>> >Changed cpdma_ctlr_eoi api to acknowledge 1 and 2 interrupts which are
>> >used for rx and tx respectively.
>> >
>> >Reported-by: Pantelis Antoniou<panto@antoniou-consulting.com>
>> >Signed-off-by: Mugunthan V N<mugunthanvnm@ti.com>
> Not sure if I'm seeing this same problem [1], but it doesn't appear fixed to me.
>
> I've tried both mainline -rc2 and -next.
>
> [1]https://lkml.org/lkml/2013/3/12/376
Without this patch, PG2.0 was not usable as CPSW interrupt was never acked
and CPU spent most of the time in CPSW ISR.
I have checked -rc2 and it is working fine.
Regards
Mugunthan V N
^ permalink raw reply
* Re: [PATCH v3 net-next 1/1] drivers: net: davinci_cpdma: acknowledge interrupt properly
From: Mark Jackson @ 2013-03-14 10:27 UTC (permalink / raw)
To: Mugunthan V N; +Cc: netdev, davem, linux-arm-kernel, linux-omap
In-Reply-To: <5141A4A3.4050204@ti.com>
On 14/03/13 10:21, Mugunthan V N wrote:
> On 3/13/2013 3:04 PM, Mark Jackson wrote:
>> On 18/02/13 08:19, Mugunthan V N wrote:
>>> >CPDMA interrupts are not properly acknowledged which leads to interrupt
>>> >storm, only cpdma interrupt 0 is acknowledged in Davinci CPDMA driver.
>>> >Changed cpdma_ctlr_eoi api to acknowledge 1 and 2 interrupts which are
>>> >used for rx and tx respectively.
>>> >
>>> >Reported-by: Pantelis Antoniou<panto@antoniou-consulting.com>
>>> >Signed-off-by: Mugunthan V N<mugunthanvnm@ti.com>
>> Not sure if I'm seeing this same problem [1], but it doesn't appear fixed to me.
>>
>> I've tried both mainline -rc2 and -next.
>>
>> [1]https://lkml.org/lkml/2013/3/12/376
> Without this patch, PG2.0 was not usable as CPSW interrupt was never acked
> and CPU spent most of the time in CPSW ISR.
>
> I have checked -rc2 and it is working fine.
I needed to add patch [1] to fix my problem. See thread [2].
[1] https://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=d35162f89b8f00537d7b240b76d2d0e8b8d29aa0
[2] https://lkml.org/lkml/2013/3/13/146
Cheers
Mark J.
^ permalink raw reply
* RE: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Eric Dumazet @ 2013-03-14 10:34 UTC (permalink / raw)
To: David Laight
Cc: Hannes Frederic Sowa, Stephen Hemminger, netdev, yoshfuji, brouer
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B718C@saturn3.aculab.com>
On Thu, 2013-03-14 at 09:47 +0000, David Laight wrote:
> I'd also have thought that INETFRAGS_MAXDEPTH should be run-time tunable.
The useful thing would be to be able to resize the hash table, for some
heavy user cases.
Check net/ipv4/tcp_metrics.c : Not only we use a small depth, but is not
tunable.
#define TCP_METRICS_RECLAIM_DEPTH 5
^ permalink raw reply
* [PATCH] phy: Elimination the forced speed reduction algorithm.
From: Kirill Kapranov @ 2013-03-14 10:40 UTC (permalink / raw)
To: netdev
Cc: davem, bhutchings, peppe.cavallaro, joe, bruce.w.allan,
linux-kernel, Kirill Kapranov
In case of fixed speed set up for a NIC (e.g. ethtool -s eth0 autoneg off speed
100 duplex full) with an ethernet cable plugged off, the mentioned algorithm
slows down a NIC speed, so further cable hook-up leads to nonoperable link state.
Signed-off-by: Kirill Kapranov <kapranoff@inbox.ru>
---
drivers/net/phy/phy.c | 47 -----------------------------------------------
1 files changed, 0 insertions(+), 47 deletions(-)
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index ef9ea92..0e40170 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -463,33 +463,6 @@ void phy_stop_machine(struct phy_device *phydev)
}
/**
- * phy_force_reduction - reduce PHY speed/duplex settings by one step
- * @phydev: target phy_device struct
- *
- * Description: Reduces the speed/duplex settings by one notch,
- * in this order--
- * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF.
- * The function bottoms out at 10/HALF.
- */
-static void phy_force_reduction(struct phy_device *phydev)
-{
- int idx;
-
- idx = phy_find_setting(phydev->speed, phydev->duplex);
-
- idx++;
-
- idx = phy_find_valid(idx, phydev->supported);
-
- phydev->speed = settings[idx].speed;
- phydev->duplex = settings[idx].duplex;
-
- pr_info("Trying %d/%s\n",
- phydev->speed, DUPLEX_FULL == phydev->duplex ? "FULL" : "HALF");
-}
-
-
-/**
* phy_error - enter HALTED state for this PHY device
* @phydev: target phy_device struct
*
@@ -818,30 +791,11 @@ void phy_state_machine(struct work_struct *work)
phydev->adjust_link(phydev->attached_dev);
} else if (0 == phydev->link_timeout--) {
- int idx;
-
needs_aneg = 1;
/* If we have the magic_aneg bit,
* we try again */
if (phydev->drv->flags & PHY_HAS_MAGICANEG)
break;
-
- /* The timer expired, and we still
- * don't have a setting, so we try
- * forcing it until we find one that
- * works, starting from the fastest speed,
- * and working our way down */
- idx = phy_find_valid(0, phydev->supported);
-
- phydev->speed = settings[idx].speed;
- phydev->duplex = settings[idx].duplex;
-
- phydev->autoneg = AUTONEG_DISABLE;
-
- pr_info("Trying %d/%s\n",
- phydev->speed,
- DUPLEX_FULL == phydev->duplex ?
- "FULL" : "HALF");
}
break;
case PHY_NOLINK:
@@ -867,7 +821,6 @@ void phy_state_machine(struct work_struct *work)
netif_carrier_on(phydev->attached_dev);
} else {
if (0 == phydev->link_timeout--) {
- phy_force_reduction(phydev);
needs_aneg = 1;
}
}
--
1.7.2.5
^ permalink raw reply related
* [PATCH net,stable-3.8] net: cdc_ncm, cdc_mbim: allow user to prefer NCM for backwards compatibility
From: Bjørn Mork @ 2013-03-14 11:05 UTC (permalink / raw)
To: netdev; +Cc: linux-usb, Bjørn Mork, Greg Suarez, Alexey Orishko
commit bd329e1 ("net: cdc_ncm: do not bind to NCM compatible MBIM devices")
introduced a new policy, preferring MBIM for dual NCM/MBIM functions if
the cdc_mbim driver was enabled. This caused a regression for users
wanting to use NCM.
Devices implementing NCM backwards compatibility according to section
3.2 of the MBIM v1.0 specification allow either NCM or MBIM on a single
USB function, using different altsettings. The cdc_ncm and cdc_mbim
drivers will both probe such functions, and must agree on a common
policy for selecting either MBIM or NCM. Until now, this policy has
been set at build time based on CONFIG_USB_NET_CDC_MBIM.
Use a module parameter to set the system policy at runtime, allowing the
user to prefer NCM on systems with the cdc_mbim driver.
Cc: Greg Suarez <gsuarez@smithmicro.com>
Cc: Alexey Orishko <alexey.orishko@stericsson.com>
Reported-by: Geir Haatveit <nospam@haatveit.nu>
Reported-by: Tommi Kyntola <kynde@ts.ray.fi>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=54791
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
We now have two users independently reporting this as a 3.8 regression,
so something needs to be done. I am not sure if adding a new module
parameter is acceptable for stable, but this problem is definitely a
regression and no other solutions came up in response to my RFC.
The only real alternative I see for stable, is disabling MBIM support
on any dual NCM/MBIM function. Which of course will be a regression
for any user wanting MBIM, making it unacceptable.
drivers/net/usb/cdc_mbim.c | 11 +---------
drivers/net/usb/cdc_ncm.c | 49 ++++++++++++++++++++++++++++---------------
include/linux/usb/cdc_ncm.h | 1 +
3 files changed, 34 insertions(+), 27 deletions(-)
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c
index 248d2dc..16c8429 100644
--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -68,18 +68,9 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf)
struct cdc_ncm_ctx *ctx;
struct usb_driver *subdriver = ERR_PTR(-ENODEV);
int ret = -ENODEV;
- u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM;
+ u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf);
struct cdc_mbim_state *info = (void *)&dev->data;
- /* see if interface supports MBIM alternate setting */
- if (intf->num_altsetting == 2) {
- if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
- usb_set_interface(dev->udev,
- intf->cur_altsetting->desc.bInterfaceNumber,
- CDC_NCM_COMM_ALTSETTING_MBIM);
- data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM;
- }
-
/* Probably NCM, defer for cdc_ncm_bind */
if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
goto err;
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 61b74a2..4709fa3 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -55,6 +55,14 @@
#define DRIVER_VERSION "14-Mar-2012"
+#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
+static bool prefer_mbim = true;
+#else
+static bool prefer_mbim;
+#endif
+module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions");
+
static void cdc_ncm_txpath_bh(unsigned long param);
static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx);
static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer);
@@ -550,9 +558,12 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
}
EXPORT_SYMBOL_GPL(cdc_ncm_unbind);
-static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
+/* Select the MBIM altsetting iff it is preferred and available,
+ * returning the number of the corresponding data interface altsetting
+ */
+u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf)
{
- int ret;
+ struct usb_host_interface *alt;
/* The MBIM spec defines a NCM compatible default altsetting,
* which we may have matched:
@@ -568,23 +579,27 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
* endpoint descriptors, shall be constructed according to
* the rules given in section 6 (USB Device Model) of this
* specification."
- *
- * Do not bind to such interfaces, allowing cdc_mbim to handle
- * them
*/
-#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
- if ((intf->num_altsetting == 2) &&
- !usb_set_interface(dev->udev,
- intf->cur_altsetting->desc.bInterfaceNumber,
- CDC_NCM_COMM_ALTSETTING_MBIM)) {
- if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
- return -ENODEV;
- else
- usb_set_interface(dev->udev,
- intf->cur_altsetting->desc.bInterfaceNumber,
- CDC_NCM_COMM_ALTSETTING_NCM);
+ if (prefer_mbim && intf->num_altsetting == 2) {
+ alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM);
+ if (alt && cdc_ncm_comm_intf_is_mbim(alt) &&
+ !usb_set_interface(dev->udev,
+ intf->cur_altsetting->desc.bInterfaceNumber,
+ CDC_NCM_COMM_ALTSETTING_MBIM))
+ return CDC_NCM_DATA_ALTSETTING_MBIM;
}
-#endif
+ return CDC_NCM_DATA_ALTSETTING_NCM;
+}
+EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting);
+
+static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+
+ /* MBIM backwards compatible function? */
+ cdc_ncm_select_altsetting(dev, intf);
+ if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting))
+ return -ENODEV;
/* NCM data altsetting is always 1 */
ret = cdc_ncm_bind_common(dev, intf, 1);
diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h
index 3b8f9d4..cc25b70 100644
--- a/include/linux/usb/cdc_ncm.h
+++ b/include/linux/usb/cdc_ncm.h
@@ -127,6 +127,7 @@ struct cdc_ncm_ctx {
u16 connected;
};
+extern u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf);
extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting);
extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf);
extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign);
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH v2 2/7] USB: serial: handle suspend failure path correctly
From: Johan Hovold @ 2013-03-14 11:10 UTC (permalink / raw)
To: Ming Lei
Cc: David S. Miller, Greg Kroah-Hartman, Jiri Kosina, Alan Stern,
Oliver Neukum, netdev, linux-usb, linux-input, Johan Hovold
In-Reply-To: <1362672924-22975-3-git-send-email-ming.lei@canonical.com>
On Fri, Mar 08, 2013 at 12:15:19AM +0800, Ming Lei wrote:
> This patch kills traffic even though type->suspend returns
> failure inside usb_serial_suspend from system sleep context
> because USB core ignores the failiure and lets system sleep
> go ahread, so the serial URB traffic need to be killed
> in this case.
>
> Cc: Johan Hovold <jhovold@gmail.com>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
> drivers/usb/serial/usb-serial.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
> index a19ed74..9d0b9c8 100644
> --- a/drivers/usb/serial/usb-serial.c
> +++ b/drivers/usb/serial/usb-serial.c
> @@ -1142,10 +1142,11 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
>
> if (serial->type->suspend) {
> r = serial->type->suspend(serial, message);
> - if (r < 0) {
> + if (r < 0 && PMSG_IS_AUTO(message)) {
> serial->suspending = 0;
> goto err_out;
> }
> + /* TODO: resume() might need to handle suspend failure */
> }
>
> for (i = 0; i < serial->num_ports; ++i) {
Sorry for the late reply.
The usb-serial subdriver suspend callbacks do not and must not return
non-zero if !PMSG_IS_AUTO(message) so adding code to handle that case
merely obfuscates this fact.
I'd rather see this documented with a comment just as Bjørn suggested
for cdc_mbim and qmi_wwan.
Thanks,
Johan
^ permalink raw reply
* Re: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Hannes Frederic Sowa @ 2013-03-14 12:34 UTC (permalink / raw)
To: David Laight; +Cc: Stephen Hemminger, Eric Dumazet, netdev, yoshfuji, brouer
In-Reply-To: <AE90C24D6B3A694183C094C60CF0A2F6026B718C@saturn3.aculab.com>
On Thu, Mar 14, 2013 at 09:47:24AM -0000, David Laight wrote:
> > On Wed, Mar 13, 2013 at 09:36:52PM -0700, Stephen Hemminger wrote:
> > > > +#define INET_FRAG_FIND_CHECK(val) \
> > > > + ({ \
> > > > + static const char ___mem[] = \
> > > > + KERN_ERR pr_fmt( \
> > > > + "inet_frag_find: No memory left." \
> > > > + " Dropping fragment.\n"); \
> > > > + static const char ___limit[] = \
> > > > + KERN_WARNING pr_fmt( \
> > > > + "inet_frag_find: Fragment hash bucket" \
> > > > + " list length grew above limit " \
> > > > + __stringify(INETFRAGS_MAXDEPTH) \
> > > > + ". Dropping fragment.\n"); \
> > > > + bool ___b = true; \
> > > > + if (IS_ERR_OR_NULL(val)) { \
> > > > + ___b = false; \
> > > > + if (PTR_ERR(val) == -ENOBUFS) \
> > > > + LIMIT_NETDEBUG(___limit); \
> > > > + else \
> > > > + LIMIT_NETDEBUG(___mem); \
> > > > + } \
> > > > + ___b; \
> > > > + })
> > > > +
> > >
> > > Big macros suck, write it as an inline function or better yet a real function.
> >
> > I switched to the macro to have string expansion with pr_fmt. So it is visible
> > from the dmesg if IPv4, IPv6 or IPv6-nf did generate the message. This could
> > be done with a function, too, but would require a bit more string handling.
>
> I'd guess it would be best to have the IS_ERR_OR_NULL() inline calling a
> real function on error.
I'll explore later on how to achieve this. My rational was to
not do dynamic string handling to build the error messages. Perhaps I
can achieve both at the same time. :)
> I'd also have thought that INETFRAGS_MAXDEPTH should be run-time tunable.
128 is actually a pretty high limit. Have you seen the patch I posted before
this one? I tried to come up with a solution to dynamically calculate
max_depth based on the max_thresh of the fragmentation cache. What do you
think about that solution?
Thanks!
^ permalink raw reply
* [net-next 0/2] be2net patch set
From: Somnath Kotur @ 2013-03-14 12:41 UTC (permalink / raw)
To: netdev; +Cc: Somnath Kotur
Pls apply.
Somnath Kotur (2):
be2net: enable interrupts in be_probe() (RoCE and other ULPs need
them)
be2net: Use new F/W mailbox cmd to manipulate interrupts.
drivers/net/ethernet/emulex/benet/be_cmds.c | 25 +++++++++++++++++
drivers/net/ethernet/emulex/benet/be_cmds.h | 8 +++++
drivers/net/ethernet/emulex/benet/be_main.c | 38 ++++++++++++++++----------
3 files changed, 56 insertions(+), 15 deletions(-)
^ permalink raw reply
* [net-next 1/2] be2net: enable interrupts in be_probe() (RoCE and other ULPs need them)
From: Somnath Kotur @ 2013-03-14 12:41 UTC (permalink / raw)
To: netdev; +Cc: Somnath Kotur, Sathya Perla
As the NIC PCI function may be used by other protocols, the chip interrupts
must be enabled in be_probe() itself rather than be_open().
Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_main.c | 21 ++++++++++-----------
1 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index b8e5019..dae7172 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -157,6 +157,10 @@ static void be_intr_set(struct be_adapter *adapter, bool enable)
{
u32 reg, enabled;
+ /* On lancer interrupts can't be controlled via this register */
+ if (lancer_chip(adapter))
+ return;
+
if (adapter->eeh_error)
return;
@@ -2435,9 +2439,6 @@ static int be_close(struct net_device *netdev)
be_roce_dev_close(adapter);
- if (!lancer_chip(adapter))
- be_intr_set(adapter, false);
-
for_all_evt_queues(adapter, eqo, i)
napi_disable(&eqo->napi);
@@ -2525,9 +2526,6 @@ static int be_open(struct net_device *netdev)
be_irq_register(adapter);
- if (!lancer_chip(adapter))
- be_intr_set(adapter, true);
-
for_all_rx_queues(adapter, rxo, i)
be_cq_notify(adapter, rxo->cq.id, true, 0);
@@ -3853,6 +3851,7 @@ static void be_remove(struct pci_dev *pdev)
return;
be_roce_dev_remove(adapter);
+ be_intr_set(adapter, false);
cancel_delayed_work_sync(&adapter->func_recovery_work);
@@ -4142,11 +4141,11 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
goto ctrl_clean;
}
- /* The INTR bit may be set in the card when probed by a kdump kernel
- * after a crash.
- */
- if (!lancer_chip(adapter))
- be_intr_set(adapter, false);
+ /* Wait for interrupts to quiesce after an FLR */
+ msleep(100);
+
+ /* Allow interrupts for other ULPs running on NIC function */
+ be_intr_set(adapter, true);
status = be_stats_init(adapter);
if (status)
--
1.5.6.1
^ permalink raw reply related
* [net-next 2/2] be2net: Use new F/W mailbox cmd to manipulate interrupts.
From: Somnath Kotur @ 2013-03-14 12:42 UTC (permalink / raw)
To: netdev; +Cc: Somnath Kotur
This is needed as the earlier method of manipulating this register via PCI
Config space is disallowed by certain Hypervisors.
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
---
drivers/net/ethernet/emulex/benet/be_cmds.c | 25 +++++++++++++++++++++++++
drivers/net/ethernet/emulex/benet/be_cmds.h | 8 ++++++++
drivers/net/ethernet/emulex/benet/be_main.c | 25 +++++++++++++++++--------
3 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 6ed4639..9916364 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -3202,6 +3202,31 @@ err:
return status;
}
+int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable)
+{
+ struct be_mcc_wrb *wrb;
+ struct be_cmd_req_intr_set *req;
+ int status;
+
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+ wrb = wrb_from_mbox(adapter);
+
+ req = embedded_payload(wrb);
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_SET_INTERRUPT_ENABLE, sizeof(*req),
+ wrb, NULL);
+
+ req->intr_enabled = intr_enable;
+
+ status = be_mbox_notify_wait(adapter);
+
+ mutex_unlock(&adapter->mbox_lock);
+ return status;
+}
+
int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
{
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 6ef4575..f2af855 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -188,6 +188,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_BEACON_STATE 70
#define OPCODE_COMMON_READ_TRANSRECV_DATA 73
#define OPCODE_COMMON_GET_PORT_NAME 77
+#define OPCODE_COMMON_SET_INTERRUPT_ENABLE 89
#define OPCODE_COMMON_GET_PHY_DETAILS 102
#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
@@ -1791,6 +1792,12 @@ struct be_cmd_enable_disable_vf {
u8 rsvd[3];
};
+struct be_cmd_req_intr_set {
+ struct be_cmd_req_hdr hdr;
+ u8 intr_enabled;
+ u8 rsvd[3];
+};
+
static inline bool check_privilege(struct be_adapter *adapter, u32 flags)
{
return flags & adapter->cmd_privileges ? true : false;
@@ -1938,3 +1945,4 @@ extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps,
extern int be_cmd_get_if_id(struct be_adapter *adapter,
struct be_vf_cfg *vf_cfg, int vf_num);
extern int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain);
+extern int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index dae7172..c71b180 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -153,17 +153,10 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
return 0;
}
-static void be_intr_set(struct be_adapter *adapter, bool enable)
+static void be_reg_intr_set(struct be_adapter *adapter, bool enable)
{
u32 reg, enabled;
- /* On lancer interrupts can't be controlled via this register */
- if (lancer_chip(adapter))
- return;
-
- if (adapter->eeh_error)
- return;
-
pci_read_config_dword(adapter->pdev, PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET,
®);
enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
@@ -179,6 +172,22 @@ static void be_intr_set(struct be_adapter *adapter, bool enable)
PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET, reg);
}
+static void be_intr_set(struct be_adapter *adapter, bool enable)
+{
+ int status = 0;
+
+ /* On lancer interrupts can't be controlled via this register */
+ if (lancer_chip(adapter))
+ return;
+
+ if (adapter->eeh_error)
+ return;
+
+ status = be_cmd_intr_set(adapter, enable);
+ if (status)
+ be_reg_intr_set(adapter, enable);
+}
+
static void be_rxq_notify(struct be_adapter *adapter, u16 qid, u16 posted)
{
u32 val = 0;
--
1.5.6.1
^ permalink raw reply related
* Re: [PATCH RFC] ipv6: use stronger hash for reassembly queue hash table
From: Hannes Frederic Sowa @ 2013-03-14 12:45 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: Eric Dumazet, netdev, yoshfuji
In-Reply-To: <1363252690.14913.42.camel@localhost>
On Thu, Mar 14, 2013 at 10:18:10AM +0100, Jesper Dangaard Brouer wrote:
> I will start working on this as soon as Netfilter Workshop is over and I
> have recovered from organizing this event. DaveM told me I needed to
> finish my frag patches first, before I could implement all the other
> cool ideas we have come up with during the workshop ;-)
Yeah, I have had a look at your patches, looks promising. Definitely worth
that you get some pressure to finish them. :)
> But I don't know if my frag changes can make v3.9, maybe v3.10 is more
> realistic? In which case we should use your patch to close this problem
> on v3.9 IMHO.
Sounds good.
^ permalink raw reply
* [PATCH] skb: Propagate pfmemalloc on skb from head page only
From: Pavel Emelyanov @ 2013-03-14 13:29 UTC (permalink / raw)
To: David Miller, Mel Gorman, Eric Dumazet, Linux Netdev List, stable
Cc: Alexey Kuznetsov
Hi.
I'm trying to send big chunks of memory from application address space via
TCP socket using vmsplice + splice like this
mem = mmap(128Mb);
vmsplice(pipe[1], mem); /* splice memory into pipe */
splice(pipe[0], tcp_socket); /* send it into network */
When I'm lucky and a huge page splices into the pipe and then into the socket
_and_ client and server ends of the TCP connection are on the same host,
communicating via lo, the whole connection gets stuck! The sending queue
becomes full and app stops writing/splicing more into it, but the receiving
queue remains empty, and that's why.
The __skb_fill_page_desc observes a tail page of a huge page and erroneously
propagates its page->pfmemalloc value onto socket (the pfmemalloc on tail pages
contain garbage). Then this skb->pfmemalloc leaks through lo and due to the
tcp_v4_rcv
sk_filter
if (skb->pfmemalloc && !sock_flag(sk, SOCK_MEMALLOC)) /* true */
return -ENOMEM
goto release_and_discard;
no packets reach the socket. Even TCP re-transmits are dropped by this, as skb
cloning clones the pfmemalloc flag as well.
That said, here's the proper page->pfmemalloc propagation onto socket: we
must check the huge-page's head page only, other pages' pfmemalloc and mapping
values do not contain what is expected in this place. However, I'm not sure
whether this fix is _complete_, since pfmemalloc propagation via lo also
oesn't look great.
Both, bit propagation from page to skb and this check in sk_filter, were
introduced by c48a11c7 (netvm: propagate page->pfmemalloc to skb), in v3.5 so
Mel and stable@ are in Cc.
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
---
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index eb2106f..4e525eb 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1292,11 +1292,13 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
* do not lose pfmemalloc information as the pages would not be
* allocated using __GFP_MEMALLOC.
*/
- if (page->pfmemalloc && !page->mapping)
- skb->pfmemalloc = true;
frag->page.p = page;
frag->page_offset = off;
skb_frag_size_set(frag, size);
+
+ page = compound_head(page);
+ if (page->pfmemalloc && !page->mapping)
+ skb->pfmemalloc = true;
}
/**
^ permalink raw reply related
* Re: [PATCH] skb: Propagate pfmemalloc on skb from head page only
From: Eric Dumazet @ 2013-03-14 14:16 UTC (permalink / raw)
To: Pavel Emelyanov
Cc: David Miller, Mel Gorman, Linux Netdev List, stable,
Alexey Kuznetsov
In-Reply-To: <5141D0C4.70409@parallels.com>
On Thu, 2013-03-14 at 17:29 +0400, Pavel Emelyanov wrote:
> Hi.
>
> I'm trying to send big chunks of memory from application address space via
> TCP socket using vmsplice + splice like this
>
> mem = mmap(128Mb);
> vmsplice(pipe[1], mem); /* splice memory into pipe */
> splice(pipe[0], tcp_socket); /* send it into network */
>
> When I'm lucky and a huge page splices into the pipe and then into the socket
> _and_ client and server ends of the TCP connection are on the same host,
> communicating via lo, the whole connection gets stuck! The sending queue
> becomes full and app stops writing/splicing more into it, but the receiving
> queue remains empty, and that's why.
>
> The __skb_fill_page_desc observes a tail page of a huge page and erroneously
> propagates its page->pfmemalloc value onto socket (the pfmemalloc on tail pages
> contain garbage). Then this skb->pfmemalloc leaks through lo and due to the
>
> tcp_v4_rcv
> sk_filter
> if (skb->pfmemalloc && !sock_flag(sk, SOCK_MEMALLOC)) /* true */
> return -ENOMEM
> goto release_and_discard;
>
> no packets reach the socket. Even TCP re-transmits are dropped by this, as skb
> cloning clones the pfmemalloc flag as well.
>
> That said, here's the proper page->pfmemalloc propagation onto socket: we
> must check the huge-page's head page only, other pages' pfmemalloc and mapping
> values do not contain what is expected in this place. However, I'm not sure
> whether this fix is _complete_, since pfmemalloc propagation via lo also
> oesn't look great.
>
> Both, bit propagation from page to skb and this check in sk_filter, were
> introduced by c48a11c7 (netvm: propagate page->pfmemalloc to skb), in v3.5 so
> Mel and stable@ are in Cc.
>
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
>
> ---
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index eb2106f..4e525eb 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -1292,11 +1292,13 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
> * do not lose pfmemalloc information as the pages would not be
> * allocated using __GFP_MEMALLOC.
> */
> - if (page->pfmemalloc && !page->mapping)
> - skb->pfmemalloc = true;
> frag->page.p = page;
> frag->page_offset = off;
> skb_frag_size_set(frag, size);
> +
> + page = compound_head(page);
> + if (page->pfmemalloc && !page->mapping)
> + skb->pfmemalloc = true;
> }
>
> /**
> --
This looks a nice finding.
Note this can trigger even without vmsplice() use but regular network
receive.
Acked-by: Eric Dumazet <edumazet@google.com>
When I discussed with David on this issue, I said that one possibility
would be to accept a pfmemalloc skb on regular skb if no other packet is
in a receive queue, to get a chance to make progress (and limit memory
consumption to no more than one skb per TCP socket)
^ permalink raw reply
* Re: [PATCH] skb: Propagate pfmemalloc on skb from head page only
From: Pavel Emelyanov @ 2013-03-14 14:23 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Mel Gorman, Linux Netdev List, stable,
Alexey Kuznetsov
In-Reply-To: <1363270569.29475.11.camel@edumazet-glaptop>
>> That said, here's the proper page->pfmemalloc propagation onto socket: we
>> must check the huge-page's head page only, other pages' pfmemalloc and mapping
>> values do not contain what is expected in this place. However, I'm not sure
>> whether this fix is _complete_, since pfmemalloc propagation via lo also
>> oesn't look great.
>>
>> Both, bit propagation from page to skb and this check in sk_filter, were
>> introduced by c48a11c7 (netvm: propagate page->pfmemalloc to skb), in v3.5 so
>> Mel and stable@ are in Cc.
>>
>> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
>>
>> ---
>>
>> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
>> index eb2106f..4e525eb 100644
>> --- a/include/linux/skbuff.h
>> +++ b/include/linux/skbuff.h
>> @@ -1292,11 +1292,13 @@ static inline void __skb_fill_page_desc(struct sk_buff *skb, int i,
>> * do not lose pfmemalloc information as the pages would not be
>> * allocated using __GFP_MEMALLOC.
>> */
>> - if (page->pfmemalloc && !page->mapping)
>> - skb->pfmemalloc = true;
>> frag->page.p = page;
>> frag->page_offset = off;
>> skb_frag_size_set(frag, size);
>> +
>> + page = compound_head(page);
>> + if (page->pfmemalloc && !page->mapping)
>> + skb->pfmemalloc = true;
>> }
>>
>> /**
>> --
>
> This looks a nice finding.
>
> Note this can trigger even without vmsplice() use but regular network
> receive.
Presumably you're right, but I don't understand how :( In order to trigger
this, we should have a huge page, that gets linked to an skb _before_ it
enters the TCP receive path. How can this happen when doing sendmsg/recvmsg?
> Acked-by: Eric Dumazet <edumazet@google.com>
>
> When I discussed with David on this issue, I said that one possibility
> would be to accept a pfmemalloc skb on regular skb if no other packet is
> in a receive queue, to get a chance to make progress (and limit memory
> consumption to no more than one skb per TCP socket)
Thanks,
Pavel
^ permalink raw reply
* Re: [PATCH] skb: Propagate pfmemalloc on skb from head page only
From: Mel Gorman @ 2013-03-14 14:28 UTC (permalink / raw)
To: Pavel Emelyanov
Cc: David Miller, Eric Dumazet, Linux Netdev List, stable,
Alexey Kuznetsov
In-Reply-To: <5141D0C4.70409@parallels.com>
On Thu, Mar 14, 2013 at 05:29:40PM +0400, Pavel Emelyanov wrote:
> Hi.
>
> I'm trying to send big chunks of memory from application address space via
> TCP socket using vmsplice + splice like this
>
> mem = mmap(128Mb);
> vmsplice(pipe[1], mem); /* splice memory into pipe */
> splice(pipe[0], tcp_socket); /* send it into network */
>
> When I'm lucky and a huge page splices into the pipe and then into the socket
> _and_ client and server ends of the TCP connection are on the same host,
> communicating via lo, the whole connection gets stuck! The sending queue
> becomes full and app stops writing/splicing more into it, but the receiving
> queue remains empty, and that's why.
>
> The __skb_fill_page_desc observes a tail page of a huge page and erroneously
> propagates its page->pfmemalloc value onto socket (the pfmemalloc on tail pages
> contain garbage). Then this skb->pfmemalloc leaks through lo and due to the
>
> tcp_v4_rcv
> sk_filter
> if (skb->pfmemalloc && !sock_flag(sk, SOCK_MEMALLOC)) /* true */
> return -ENOMEM
> goto release_and_discard;
>
> no packets reach the socket. Even TCP re-transmits are dropped by this, as skb
> cloning clones the pfmemalloc flag as well.
>
> That said, here's the proper page->pfmemalloc propagation onto socket: we
> must check the huge-page's head page only, other pages' pfmemalloc and mapping
> values do not contain what is expected in this place. However, I'm not sure
> whether this fix is _complete_, since pfmemalloc propagation via lo also
> oesn't look great.
>
> Both, bit propagation from page to skb and this check in sk_filter, were
> introduced by c48a11c7 (netvm: propagate page->pfmemalloc to skb), in v3.5 so
> Mel and stable@ are in Cc.
>
> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
>
Acked-by: Mel Gorman <mgorman@suse.de>
--
Mel Gorman
SUSE Labs
^ permalink raw reply
* Re: atl1c issues on 3.8.2
From: Eric Dumazet @ 2013-03-14 14:31 UTC (permalink / raw)
To: Michael Büsch, Pavel Emelyanov
Cc: Eric Dumazet, linux-netdev, David S.Miller, Mel Gorman
In-Reply-To: <1363154258.13690.40.camel@edumazet-glaptop>
On Wed, 2013-03-13 at 06:57 +0100, Eric Dumazet wrote:
> On Tue, 2013-03-12 at 18:09 +0100, Michael Büsch wrote:
> > On Tue, 12 Mar 2013 16:45:44 +0100
> > Eric Dumazet <eric.dumazet@gmail.com> wrote:
> >
> > > On Tue, 2013-03-12 at 16:17 +0100, Michael Büsch wrote:
> > > > Hi,
> > > >
> > > > Starting with 3.8.x scp stalls the atl1c based interface on my Asus Eeepc 1011px.
> > > > iperf (for example) does not do that. But after scp stalled the interface,
> > > > iperf transfers fail, too.
> > >
> > > I am pretty sure David stable list contains the needed fix
> > >
> > > http://patchwork.ozlabs.org/bundle/davem/stable/?state=*
> >
> > No this didn't fix it.
> >
> > However, I tried to revert 69b08f62e17439ee3d436faf0b9a7ca6fffb78db again,
> > which already caused trouble for me in 3.7
> > and this fixed the issue.
> >
> > So it seems that this still is the same or a related issue that I reported
> > for 3.7. I just wrongly stated that the problem was fixed in 3.8, because my
> > simple ping test doesn't catch it on 3.8.
> >
>
>
And it seems the possible fix is here :
http://patchwork.ozlabs.org/patch/227666/
^ permalink raw reply
* Re: [PATCH] skb: Propagate pfmemalloc on skb from head page only
From: Eric Dumazet @ 2013-03-14 14:34 UTC (permalink / raw)
To: Pavel Emelyanov
Cc: David Miller, Mel Gorman, Linux Netdev List, stable,
Alexey Kuznetsov
In-Reply-To: <5141DD72.6030906@parallels.com>
On Thu, 2013-03-14 at 18:23 +0400, Pavel Emelyanov wrote:
> Presumably you're right, but I don't understand how :( In order to trigger
> this, we should have a huge page, that gets linked to an skb _before_ it
> enters the TCP receive path. How can this happen when doing sendmsg/recvmsg?
Not only huge pages.
network now uses order-3 pages in both transmit and receive paths.
^ permalink raw reply
* Re: [PATCH] skb: Propagate pfmemalloc on skb from head page only
From: Pavel Emelyanov @ 2013-03-14 14:36 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Mel Gorman, Linux Netdev List, stable,
Alexey Kuznetsov
In-Reply-To: <1363271649.29475.18.camel@edumazet-glaptop>
On 03/14/2013 06:34 PM, Eric Dumazet wrote:
> On Thu, 2013-03-14 at 18:23 +0400, Pavel Emelyanov wrote:
>
>> Presumably you're right, but I don't understand how :( In order to trigger
>> this, we should have a huge page, that gets linked to an skb _before_ it
>> enters the TCP receive path. How can this happen when doing sendmsg/recvmsg?
>
> Not only huge pages.
>
> network now uses order-3 pages in both transmit and receive paths.
Ah, indeed! Thanks, Eric.
^ permalink raw reply
* Re: [RFC PATCH] udp: don't rereference dst_entry dev pointer on rcv
From: Tom Parkin @ 2013-03-14 14:45 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1363223884.29475.0.camel@edumazet-glaptop>
[-- Attachment #1: Type: text/plain, Size: 719 bytes --]
On Thu, Mar 14, 2013 at 02:18:04AM +0100, Eric Dumazet wrote:
> Ah thanks for this, as this definitely makes more sense ;)
>
> Could you try the following fix ?
>
> diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
> index b6d30ac..87f4ecb 100644
> --- a/net/ipv4/ip_fragment.c
> +++ b/net/ipv4/ip_fragment.c
> @@ -529,6 +529,7 @@ found:
> qp->q.meat == qp->q.len)
> return ip_frag_reasm(qp, prev, dev);
>
> + skb_dst_force(skb);
> inet_frag_lru_move(&qp->q);
> return -EINPROGRESS;
>
Thanks Eric, with this patch I can no longer reproduce the oops :-)
--
Tom Parkin
Katalix Systems Ltd
http://www.katalix.com
Catalysts for your Embedded Linux software development
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 2/4] bridge: Allow an ability to designate an uplink port
From: Dan Williams @ 2013-03-14 14:53 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: Vlad Yasevich, netdev, bridge
In-Reply-To: <20130313203333.GC9821@redhat.com>
On Wed, 2013-03-13 at 22:33 +0200, Michael S. Tsirkin wrote:
> On Tue, Mar 12, 2013 at 09:45:24PM -0400, Vlad Yasevich wrote:
> > Allow a ports to be designated as uplink. Multiple ports
> > may be designated as uplinks and they will be kept in a
> > list.
> >
> > Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
>
> It looks like if you make two links uplink, bridging
> between them won't work at all?
Only caught the end of this thread... is there any way to use the
UPLINK flag as part of the bridge master carrier calculation? Obviously
that's technically possible, I'm asking if that's going to break all
sorts of userspace tools and such.
Traditionally for "wired-type" devices like bridge, bond, vlan, wired,
etc, the carrier/LOWER_UP is the way that higher levels know that IP
configuration is possible on the device.
In the case of a bridge, it's not worth trying DHCP or IPv6 RA on the
bridge master until we know that there's an uplink port, otherwise it's
just going to fail. But right now, we have no way of knowing which port
is an uplink port, which this series would clearly solve.
However, bridge master devices calculate their carrier based on the
state of all their ports, but right now all ports are equal. If we used
UPLINK as part of that calculation, then higher level tools would be
notified that the master is LOWER_UP only when it actually was.
If we're worried about backwards compatibility, then perhaps the new
behavior could be enabled only if one or more ports was an UPLINK? Then
userspace tools that cared would monitor bridge ports, and if they cared
about UPLINK could ignore bridge carrier until at least one UPLINK port
was added.
Dan
> > ---
> > include/uapi/linux/if_link.h | 1 +
> > net/bridge/br_netlink.c | 2 ++
> > net/bridge/br_private.h | 1 +
> > net/bridge/br_sysfs_if.c | 2 ++
> > 4 files changed, 6 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> > index c4edfe1..b9444e9 100644
> > --- a/include/uapi/linux/if_link.h
> > +++ b/include/uapi/linux/if_link.h
> > @@ -220,6 +220,7 @@ enum {
> > IFLA_BRPORT_GUARD, /* bpdu guard */
> > IFLA_BRPORT_PROTECT, /* root port protection */
> > IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */
> > + IFLA_BRPORT_UPLINK, /* uplink port */
> > __IFLA_BRPORT_MAX
> > };
> > #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
> > diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
> > index 27aa3ee..e08a50e 100644
> > --- a/net/bridge/br_netlink.c
> > +++ b/net/bridge/br_netlink.c
> > @@ -283,6 +283,7 @@ static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = {
> > [IFLA_BRPORT_MODE] = { .type = NLA_U8 },
> > [IFLA_BRPORT_GUARD] = { .type = NLA_U8 },
> > [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 },
> > + [IFLA_BRPORT_UPLINK] = { .type = NLA_U8 },
> > };
> >
> > /* Change the state of the port and notify spanning tree */
> > @@ -329,6 +330,7 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
> > br_set_port_flag(p, tb, IFLA_BRPORT_MODE, BR_HAIRPIN_MODE);
> > br_set_port_flag(p, tb, IFLA_BRPORT_GUARD, BR_BPDU_GUARD);
> > br_set_port_flag(p, tb, IFLA_BRPORT_FAST_LEAVE, BR_MULTICAST_FAST_LEAVE);
> > + br_set_port_flag(p, tb, IFLA_BRPORT_UPLINK, BR_UPLINK);
> >
> > if (tb[IFLA_BRPORT_COST]) {
> > err = br_stp_set_path_cost(p, nla_get_u32(tb[IFLA_BRPORT_COST]));
> > diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
> > index 4a0fa29..44ae584 100644
> > --- a/net/bridge/br_private.h
> > +++ b/net/bridge/br_private.h
> > @@ -156,6 +156,7 @@ struct net_bridge_port
> > #define BR_BPDU_GUARD 0x00000002
> > #define BR_ROOT_BLOCK 0x00000004
> > #define BR_MULTICAST_FAST_LEAVE 0x00000008
> > +#define BR_UPLINK 0x00000010
> >
> > #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> > u32 multicast_startup_queries_sent;
> > diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
> > index a1ef1b6..1f28cd4 100644
> > --- a/net/bridge/br_sysfs_if.c
> > +++ b/net/bridge/br_sysfs_if.c
> > @@ -158,6 +158,7 @@ static BRPORT_ATTR(flush, S_IWUSR, NULL, store_flush);
> > BRPORT_ATTR_FLAG(hairpin_mode, BR_HAIRPIN_MODE);
> > BRPORT_ATTR_FLAG(bpdu_guard, BR_BPDU_GUARD);
> > BRPORT_ATTR_FLAG(root_block, BR_ROOT_BLOCK);
> > +BRPORT_ATTR_FLAG(uplink, BR_UPLINK);
> >
> > #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> > static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
> > @@ -195,6 +196,7 @@ static const struct brport_attribute *brport_attrs[] = {
> > &brport_attr_hairpin_mode,
> > &brport_attr_bpdu_guard,
> > &brport_attr_root_block,
> > + &brport_attr_uplink,
> > #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
> > &brport_attr_multicast_router,
> > &brport_attr_multicast_fast_leave,
> > --
> > 1.7.7.6
> >
> > --
> > 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
> --
> 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
* Re: [RFC PATCH] udp: don't rereference dst_entry dev pointer on rcv
From: Eric Dumazet @ 2013-03-14 15:05 UTC (permalink / raw)
To: Tom Parkin; +Cc: David Miller, netdev
In-Reply-To: <20130314144550.GB2512@raven>
On Thu, 2013-03-14 at 14:45 +0000, Tom Parkin wrote:
> On Thu, Mar 14, 2013 at 02:18:04AM +0100, Eric Dumazet wrote:
> > Ah thanks for this, as this definitely makes more sense ;)
> >
> > Could you try the following fix ?
> >
> > diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
> > index b6d30ac..87f4ecb 100644
> > --- a/net/ipv4/ip_fragment.c
> > +++ b/net/ipv4/ip_fragment.c
> > @@ -529,6 +529,7 @@ found:
> > qp->q.meat == qp->q.len)
> > return ip_frag_reasm(qp, prev, dev);
> >
> > + skb_dst_force(skb);
> > inet_frag_lru_move(&qp->q);
> > return -EINPROGRESS;
> >
>
> Thanks Eric, with this patch I can no longer reproduce the oops :-)
Thanks for testing.
I am considering an alternative patch :
We can drop the reference instead, and use the dst of the last skb.
This would help to not dirty the dst refcount.
I'll send an updated version.
^ permalink raw reply
* [PATCH v2 net-next 01/22] cxgb4: Add register definations for T5
From: Vipul Pandya @ 2013-03-14 15:08 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
linux-scsi-u79uwXL29TY76Z2rM5mHXA
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q, roland-BHEL68pLQRGGvPXPguhicg,
JBottomley-bzQdu9zFT3WakBO8gow8eQ, dm-ut6Up61K2wZBDgjK7y7TUQ,
swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW,
leedom-ut6Up61K2wZBDgjK7y7TUQ, naresh-ut6Up61K2wZBDgjK7y7TUQ,
divy-ut6Up61K2wZBDgjK7y7TUQ, santosh-ut6Up61K2wZBDgjK7y7TUQ,
arvindb-ut6Up61K2wZBDgjK7y7TUQ, abhishek-ut6Up61K2wZBDgjK7y7TUQ,
vipul-ut6Up61K2wZBDgjK7y7TUQ
In-Reply-To: <1363273748-25330-1-git-send-email-vipul-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
From: Santosh Rastapur <santosh-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Santosh Rastapur <santosh-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
Signed-off-by: Vipul Pandya <vipul-ut6Up61K2wZBDgjK7y7TUQ@public.gmane.org>
---
v2: Replaced #ifdef with portable interface wmb in ring_tx_db
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 94 ++++++++++++++++++++++++++
1 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 83ec5f7..22cbcb3 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -68,9 +68,14 @@
#define QID_SHIFT 15
#define QID(x) ((x) << QID_SHIFT)
#define DBPRIO(x) ((x) << 14)
+#define DBTYPE(x) ((x) << 13)
#define PIDX_MASK 0x00003fffU
#define PIDX_SHIFT 0
#define PIDX(x) ((x) << PIDX_SHIFT)
+#define S_PIDX_T5 0
+#define M_PIDX_T5 0x1fffU
+#define PIDX_T5(x) (((x) >> S_PIDX_T5) & M_PIDX_T5)
+
#define SGE_PF_GTS 0x4
#define INGRESSQID_MASK 0xffff0000U
@@ -152,6 +157,8 @@
#define QUEUESPERPAGEPF0_MASK 0x0000000fU
#define QUEUESPERPAGEPF0_GET(x) ((x) & QUEUESPERPAGEPF0_MASK)
+#define QUEUESPERPAGEPF1 4
+
#define SGE_INT_CAUSE1 0x1024
#define SGE_INT_CAUSE2 0x1030
#define SGE_INT_CAUSE3 0x103c
@@ -272,17 +279,36 @@
#define S_HP_INT_THRESH 28
#define M_HP_INT_THRESH 0xfU
#define V_HP_INT_THRESH(x) ((x) << S_HP_INT_THRESH)
+#define S_LP_INT_THRESH_T5 18
+#define V_LP_INT_THRESH_T5(x) ((x) << S_LP_INT_THRESH_T5)
+#define M_LP_COUNT_T5 0x3ffffU
+#define G_LP_COUNT_T5(x) (((x) >> S_LP_COUNT) & M_LP_COUNT_T5)
#define M_HP_COUNT 0x7ffU
#define S_HP_COUNT 16
#define G_HP_COUNT(x) (((x) >> S_HP_COUNT) & M_HP_COUNT)
#define S_LP_INT_THRESH 12
#define M_LP_INT_THRESH 0xfU
+#define M_LP_INT_THRESH_T5 0xfffU
#define V_LP_INT_THRESH(x) ((x) << S_LP_INT_THRESH)
#define M_LP_COUNT 0x7ffU
#define S_LP_COUNT 0
#define G_LP_COUNT(x) (((x) >> S_LP_COUNT) & M_LP_COUNT)
#define A_SGE_DBFIFO_STATUS 0x10a4
+#define SGE_STAT_TOTAL 0x10e4
+#define SGE_STAT_MATCH 0x10e8
+
+#define SGE_STAT_CFG 0x10ec
+#define S_STATSOURCE_T5 9
+#define STATSOURCE_T5(x) ((x) << S_STATSOURCE_T5)
+
+#define SGE_DBFIFO_STATUS2 0x1118
+#define M_HP_COUNT_T5 0x3ffU
+#define G_HP_COUNT_T5(x) ((x) & M_HP_COUNT_T5)
+#define S_HP_INT_THRESH_T5 10
+#define M_HP_INT_THRESH_T5 0xfU
+#define V_HP_INT_THRESH_T5(x) ((x) << S_HP_INT_THRESH_T5)
+
#define S_ENABLE_DROP 13
#define V_ENABLE_DROP(x) ((x) << S_ENABLE_DROP)
#define F_ENABLE_DROP V_ENABLE_DROP(1U)
@@ -331,8 +357,27 @@
#define MSIADDRHPERR 0x00000002U
#define MSIADDRLPERR 0x00000001U
+#define READRSPERR 0x20000000U
+#define TRGT1GRPPERR 0x10000000U
+#define IPSOTPERR 0x08000000U
+#define IPRXDATAGRPPERR 0x02000000U
+#define IPRXHDRGRPPERR 0x01000000U
+#define MAGRPPERR 0x00400000U
+#define VFIDPERR 0x00200000U
+#define HREQWRPERR 0x00010000U
+#define DREQWRPERR 0x00002000U
+#define MSTTAGQPERR 0x00000400U
+#define PIOREQGRPPERR 0x00000100U
+#define PIOCPLGRPPERR 0x00000080U
+#define MSIXSTIPERR 0x00000004U
+#define MSTTIMEOUTPERR 0x00000002U
+#define MSTGRPPERR 0x00000001U
+
#define PCIE_NONFAT_ERR 0x3010
#define PCIE_MEM_ACCESS_BASE_WIN 0x3068
+#define S_PCIEOFST 10
+#define M_PCIEOFST 0x3fffffU
+#define GET_PCIEOFST(x) (((x) >> S_PCIEOFST) & M_PCIEOFST)
#define PCIEOFST_MASK 0xfffffc00U
#define BIR_MASK 0x00000300U
#define BIR_SHIFT 8
@@ -342,6 +387,9 @@
#define WINDOW(x) ((x) << WINDOW_SHIFT)
#define PCIE_MEM_ACCESS_OFFSET 0x306c
+#define S_PFNUM 0
+#define V_PFNUM(x) ((x) << S_PFNUM)
+
#define PCIE_FW 0x30b8
#define PCIE_FW_ERR 0x80000000U
#define PCIE_FW_INIT 0x40000000U
@@ -407,12 +455,18 @@
#define MC_BIST_STATUS_RDATA 0x7688
+#define MA_EDRAM0_BAR 0x77c0
+#define MA_EDRAM1_BAR 0x77c4
+#define EDRAM_SIZE_MASK 0xfffU
+#define EDRAM_SIZE_GET(x) ((x) & EDRAM_SIZE_MASK)
+
#define MA_EXT_MEMORY_BAR 0x77c8
#define EXT_MEM_SIZE_MASK 0x00000fffU
#define EXT_MEM_SIZE_SHIFT 0
#define EXT_MEM_SIZE_GET(x) (((x) & EXT_MEM_SIZE_MASK) >> EXT_MEM_SIZE_SHIFT)
#define MA_TARGET_MEM_ENABLE 0x77d8
+#define EXT_MEM1_ENABLE 0x00000010U
#define EXT_MEM_ENABLE 0x00000004U
#define EDRAM1_ENABLE 0x00000002U
#define EDRAM0_ENABLE 0x00000001U
@@ -431,6 +485,7 @@
#define MA_PCIE_FW 0x30b8
#define MA_PARITY_ERROR_STATUS 0x77f4
+#define MA_EXT_MEMORY1_BAR 0x7808
#define EDC_0_BASE_ADDR 0x7900
#define EDC_BIST_CMD 0x7904
@@ -801,6 +856,15 @@
#define MPS_PORT_STAT_RX_PORT_PPP7_H 0x60c
#define MPS_PORT_STAT_RX_PORT_LESS_64B_L 0x610
#define MPS_PORT_STAT_RX_PORT_LESS_64B_H 0x614
+#define MAC_PORT_CFG2 0x818
+#define MAC_PORT_MAGIC_MACID_LO 0x824
+#define MAC_PORT_MAGIC_MACID_HI 0x828
+#define MAC_PORT_EPIO_DATA0 0x8c0
+#define MAC_PORT_EPIO_DATA1 0x8c4
+#define MAC_PORT_EPIO_DATA2 0x8c8
+#define MAC_PORT_EPIO_DATA3 0x8cc
+#define MAC_PORT_EPIO_OP 0x8d0
+
#define MPS_CMN_CTL 0x9000
#define NUMPORTS_MASK 0x00000003U
#define NUMPORTS_SHIFT 0
@@ -1063,6 +1127,7 @@
#define ADDRESS_SHIFT 0
#define ADDRESS(x) ((x) << ADDRESS_SHIFT)
+#define MAC_PORT_INT_CAUSE 0x8dc
#define XGMAC_PORT_INT_CAUSE 0x10dc
#define A_TP_TX_MOD_QUEUE_REQ_MAP 0x7e28
@@ -1101,4 +1166,33 @@
#define V_PORT(x) ((x) << S_PORT)
#define F_PORT V_PORT(1U)
+#define NUM_MPS_CLS_SRAM_L_INSTANCES 336
+#define NUM_MPS_T5_CLS_SRAM_L_INSTANCES 512
+
+#define T5_PORT0_BASE 0x30000
+#define T5_PORT_STRIDE 0x4000
+#define T5_PORT_BASE(idx) (T5_PORT0_BASE + (idx) * T5_PORT_STRIDE)
+#define T5_PORT_REG(idx, reg) (T5_PORT_BASE(idx) + (reg))
+
+#define MC_0_BASE_ADDR 0x40000
+#define MC_1_BASE_ADDR 0x48000
+#define MC_STRIDE (MC_1_BASE_ADDR - MC_0_BASE_ADDR)
+#define MC_REG(reg, idx) (reg + MC_STRIDE * idx)
+
+#define MC_P_BIST_CMD 0x41400
+#define MC_P_BIST_CMD_ADDR 0x41404
+#define MC_P_BIST_CMD_LEN 0x41408
+#define MC_P_BIST_DATA_PATTERN 0x4140c
+#define MC_P_BIST_STATUS_RDATA 0x41488
+#define EDC_T50_BASE_ADDR 0x50000
+#define EDC_H_BIST_CMD 0x50004
+#define EDC_H_BIST_CMD_ADDR 0x50008
+#define EDC_H_BIST_CMD_LEN 0x5000c
+#define EDC_H_BIST_DATA_PATTERN 0x50010
+#define EDC_H_BIST_STATUS_RDATA 0x50028
+
+#define EDC_T51_BASE_ADDR 0x50800
+#define EDC_STRIDE_T5 (EDC_T51_BASE_ADDR - EDC_T50_BASE_ADDR)
+#define EDC_REG_T5(reg, idx) (reg + EDC_STRIDE_T5 * idx)
+
#endif /* __T4_REGS_H */
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" 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 related
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