* Re: [PATCH iproute2] Install the bridge command under the same name we build it.
From: Li Wei @ 2012-08-06 1:51 UTC (permalink / raw)
To: Nick Alcock; +Cc: netdev, Stephen Hemminger
In-Reply-To: <87ehnmiv1m.fsf@spindle.srvr.nix>
On 08/04/2012 10:36 PM, Nick Alcock wrote:
>
> Signed-off-by: Nick Alcock <nick.alcock@oracle.com>
> ---
> bridge/Makefile | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/bridge/Makefile b/bridge/Makefile
> index 0c333bf..9a6743e 100644
> --- a/bridge/Makefile
> +++ b/bridge/Makefile
> @@ -7,8 +7,8 @@ all: bridge
> bridge: $(BROBJ) $(LIBNETLINK)
>
> install: all
> - install -m 0755 br $(DESTDIR)$(SBINDIR)
> + install -m 0755 bridge $(DESTDIR)$(SBINDIR)
>
> clean:
> - rm -f $(BROBJ) br
> + rm -f $(BROBJ) bridge
>
Hi Nick,
To post a patch for iproute2, you should send it to
Stephen Hemminger <shemminger@vyatta.com> who is the maintainer of iproute2.
Stephen, I also noticed this problem and thought should ask you for the final
name of the brige extension. Personally I prefer br, it is short and
distingushable enough.
Thanks.
^ permalink raw reply
* Re: ethtool 3.5 released
From: Naoto MATSUMOTO @ 2012-08-06 1:27 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev
In-Reply-To: <1344023317.2610.13.camel@bwh-desktop.uk.solarflarecom.com>
Dear Ben.
FYI(For Your Information)
This is Naoto MATSUMOTO, Senior Researcher, SAKURA Internet.
We tried ethtool 3.5 on 40GbE NIC(Mellanox), it's result here.
-----------------------------------------------------------------------
# ./ethtool --version
ethtool version 3.5
# ./ethtool eth1
Settings for eth1:
Supported ports: [ TP ]
Supported link modes: 10000baseT/Full
Supported pause frame use: No
Supports auto-negotiation: No
Advertised link modes: 10000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: No
Speed: 40000Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: off
MDI-X: Unknown
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000014 (20)
link ifdown
Link detected: yes
Our 40GbE NIC Firmware/Dirver status are here.
-----------------------------------------------------------------------
Mellanox ConnectX HCA Ethernet driver v1.5.8.3 (June 2012)
Ethernet controller: Mellanox Technologies MT27500 Family [ConnectX-3]
Firmware Version: 2.10.800
-----------------------------------------------------------------------
And We were testing 10GbE(Intel) NIC and your 40GbE NIC in our lab
using ethtool with added some debug code.
-----------------------------------------------------------------------
# ./ethtool-p eth5 (10GbE NIC by Intel)
Settings for eth5:
Supported ports: [ FIBRE ]
Supported link modes: 10000baseT/Full
mask == 5120 <--- ep->support number
# ./ethtool-p eth1 (40GbE NIC by Mellanox)
Settings for eth1:
Supported ports: [ TP ]
Supported link modes: 10000baseT/Full
mask == 4224 <--- ep->support number
-----------------------------------------------------------------------
It's firmware problem I thinks. But Just Information for you ;-)
regards,
--
Naoto MATSUMOTO
On Fri, 3 Aug 2012 20:48:37 +0100
Ben Hutchings <bhutchings@solarflare.com> wrote:
> ethtool version 3.5 has been released.
>
> Home page: https://ftp.kernel.org/pub/software/network/ethtool/
> Download link:
> https://ftp.kernel.org/pub/software/network/ethtool/ethtool-3.1.tar.gz
>
> Release notes:
>
> * Feature: Display support for 40G link modes
--
SAKURA Internet Inc. / Senior Researcher
Naoto MATSUMOTO <n-matsumoto@sakura.ad.jp>
SAKURA Research Center <http://research.sakura.ad.jp/>
^ permalink raw reply
* Re: [PATCH v2] ipv4/ipv6: multicast api unappropriate errno fix.
From: Li Wei @ 2012-08-06 1:19 UTC (permalink / raw)
To: David Stevens; +Cc: davem, netdev
In-Reply-To: <OF074B1468.BAD353FE-ON85257A4F.0041C4E9-85257A4F.0042D425@us.ibm.com>
On 08/03/2012 08:09 PM, David Stevens wrote:
> netdev-owner@vger.kernel.org wrote on 08/03/2012 05:29:05 AM:
>
>> @@ -1933,10 +1933,8 @@ int ip_mc_source(int add, int omode, struct
>> sock *sk, struct
>> (pmc->multi.imr_ifindex == imr.imr_ifindex))
>> break;
>> }
>> - if (!pmc) { /* must have a prior join */
>> - err = -EINVAL;
>> - goto done;
>> - }
>> + if (!pmc) /* must have a prior join */
>> + goto done; /* err = -EADDRNOTAVAIL */
>
> RFC3678, section 4.1.3:
> "When the option itself is not legal on the group (i.e., when
> trying a
> Source-Specific option on a group after doing IP_ADD_MEMBERSHIP, or
> when trying an Any-Source option without doing IP_ADD_MEMBERSHIP) the
> error generated is EINVAL."
>
>> }
>> - if (rv == 0) /* address already there is an error */
>> + if (rv == 0) { /* address already there is an error */
>> + err = -EADDRINUSE;
>> goto done;
>> + }
>
> EADDRINUSE is not one of the API's listed error codes. Section 4.1.3
> of RFC3678 specifies:
> "When the option would be legal on the group, but an address is
> invalid (e.g., when trying to block a source that is already blocked
> by the socket, or when trying to drop an unjoined group) the error
> generated is EADDRNOTAVAIL."
>
> At least some of this patch directly differs with RFC3678.
I read the RFC and found you are right, thanks :)
>
> +-DLS
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [patch 1/1] ixp4xx_eth: fix ptp_ixp46x build failure
From: Arnaud Patard @ 2012-08-05 20:30 UTC (permalink / raw)
To: netdev; +Cc: Krzysztof Halasa
[-- Attachment #1: ixp46x_build_failure.patch --]
[-- Type: text/plain, Size: 826 bytes --]
When building with ixp4xx_eth and ptp_ixp46x as module, one is getting the
following error:
ERROR: "ixp46x_phc_index" [drivers/ptp/ptp_ixp46x.ko] undefined!
This has been introduced by commit 509a7c25729feab353502e1b544c614772a1d49a.
Signed-off-by: Arnaud Patard <arnaud.patard@rtp-net.org>
Index: efika/drivers/net/ethernet/xscale/ixp4xx_eth.c
===================================================================
--- efika.orig/drivers/net/ethernet/xscale/ixp4xx_eth.c 2012-07-29 14:03:12.710197591 +0200
+++ efika/drivers/net/ethernet/xscale/ixp4xx_eth.c 2012-08-05 11:13:13.188037295 +0200
@@ -1003,6 +1003,7 @@ static int ixp4xx_nway_reset(struct net_
}
int ixp46x_phc_index = -1;
+EXPORT_SYMBOL_GPL(ixp46x_phc_index);
static int ixp4xx_get_ts_info(struct net_device *dev,
struct ethtool_ts_info *info)
^ permalink raw reply
* Re: [PATCH] can: kvaser_usb: Add support for Kvaser CAN/USB devices
From: Wolfgang Grandegger @ 2012-08-05 20:43 UTC (permalink / raw)
To: Marc Kleine-Budde; +Cc: Olivier Sobrie, linux-can, netdev
In-Reply-To: <501A6AE7.9060508@pengutronix.de>
On 08/02/2012 01:56 PM, Marc Kleine-Budde wrote:
> On 08/02/2012 12:53 PM, Olivier Sobrie wrote:
...
>> I actually implemeted it as you said and here is what I observed in
>> candump output with restart_ms set to 100 ms:
>>
>> t0: Short circuit between CAN-H and CAN-L + cansend can1 123#1122
>> can1 2000008C [8] 00 04 90 00 00 00 00 00 ERRORFRAME
>> controller-problem{rx-error-warning}
>> protocol-violation{{tx-recessive-bit-error,error-on-tx}{}}
>> bus-error
>> can1 2000008C [8] 00 10 90 00 00 00 00 00 ERRORFRAME
>> controller-problem{rx-error-passive}
>> protocol-violation{{tx-recessive-bit-error,error-on-tx}{}}
>> bus-error
>> can1 200000C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME
>> protocol-violation{{tx-recessive-bit-error,error-on-tx}{}}
>> bus-off
>> bus-error
>> ...
FYI, the option "-td" nicely shows the timing. I assume that the
"warning->passive->bus-off" sequence repeats because automatic bus-off
is active via ip option "restart-ms xx ms". What I'm missing is the
message "restarted-after-bus-off". Maybe it's not listed here...
>> can1 2000008C [8] 00 04 90 00 00 00 00 00 ERRORFRAME
>> controller-problem{rx-error-warning}
>> protocol-violation{{tx-recessive-bit-error,error-on-tx}{}}
>> bus-error
>> can1 2000008C [8] 00 10 90 00 00 00 00 00 ERRORFRAME
>> controller-problem{rx-error-passive}
>> protocol-violation{{tx-recessive-bit-error,error-on-tx}{}}
>> bus-error
>> can1 200000C8 [8] 00 00 90 00 00 00 00 00 ERRORFRAME
>> protocol-violation{{tx-recessive-bit-error,error-on-tx}{}}
>> bus-off
>> bus-error
>>
>> t1: short circuit removed
>> can1 123 [2] 11 22
>> can1 20000100 [8] 00 00 00 00 00 00 00 00 ERRORFRAME
>> restarted-after-bus-of
>>
>> The echo coming before the restart looks weird? No?
Yes. It should come later.
>> Shouldn't we drop the frame once BUF-OFF is reached?
No.
> No, I don't think so. But wait for Wolfgang, here's more into error
> handling then me.
Looking to your code it's not clear to me how you do recovery from
bus-off (called "restart"). This is usually done via
do_set_mode(CAN_MODE_START), either manually (restart-ms==0) or
automatically (restart-ms>0). Could you please explain how the device
does bus-off recovery? Does the hardware do it automatically? This
should be suppressed if if restart-ms==0 (as Marc already pointed out).
Wolfgang.
^ permalink raw reply
* Re: [PATCH] can: kvaser_usb: Add support for Kvaser CAN/USB devices
From: Wolfgang Grandegger @ 2012-08-05 20:41 UTC (permalink / raw)
To: Marc Kleine-Budde; +Cc: Olivier Sobrie, linux-can, netdev
In-Reply-To: <5017ABC6.7030307@pengutronix.de>
On 07/31/2012 11:56 AM, Marc Kleine-Budde wrote:
> On 07/30/2012 03:33 PM, Olivier Sobrie wrote:
...
>>>> +static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
>>>> + const struct kvaser_msg *msg)
>>>> +{
>>>> + struct can_frame *cf;
>>>> + struct sk_buff *skb;
>>>> + struct net_device_stats *stats;
>>>> + struct kvaser_usb_net_priv *priv;
>>>> + u8 channel, status, txerr, rxerr;
>>>> +
>>>> + if (msg->id == CMD_CAN_ERROR_EVENT) {
>>>> + channel = msg->u.error_event.channel;
>>>> + status = msg->u.error_event.status;
>>>> + txerr = msg->u.error_event.tx_errors_count;
>>>> + rxerr = msg->u.error_event.rx_errors_count;
>>>> + } else {
>>>> + channel = msg->u.chip_state_event.channel;
>>>> + status = msg->u.chip_state_event.status;
>>>> + txerr = msg->u.chip_state_event.tx_errors_count;
>>>> + rxerr = msg->u.chip_state_event.rx_errors_count;
>>>> + }
>>>> +
>>>> + if (channel >= dev->nchannels) {
>>>> + dev_err(dev->udev->dev.parent,
>>>> + "Invalid channel number (%d)\n", channel);
>>>> + return;
>>>> + }
>>>> +
>>>> + priv = dev->nets[channel];
>>>> + stats = &priv->netdev->stats;
>>>> +
>>>> + skb = alloc_can_err_skb(priv->netdev, &cf);
>>>> + if (!skb) {
>>>> + stats->rx_dropped++;
>>>> + return;
>>>> + }
>>>> +
>>>> + if ((status & M16C_STATE_BUS_OFF) ||
>>>> + (status & M16C_STATE_BUS_RESET)) {
>>>> + priv->can.state = CAN_STATE_BUS_OFF;
>>>> + cf->can_id |= CAN_ERR_BUSOFF;
>>>> + can_bus_off(priv->netdev);
>
> you should increment priv->can.can_stats.bus_off
No, already done in can_bus_off():
http://lxr.free-electrons.com/source/drivers/net/can/dev.c#L439
Wolfgang.
^ permalink raw reply
* Subject: [PATCH] sched: add missing group change to qfq_change_class
From: Paolo Valente @ 2012-08-05 19:45 UTC (permalink / raw)
To: shemminger, jhs, davem
Cc: paolo.valente, Fabio Checconi, Luigi Rizzo, netdev, linux-kernel
To speed up operations, QFQ internally divides classes into
groups. Which group a class belongs to depends on the ratio between
the maximum packet length and the weight of the class. Unfortunately
the function qfq_change_class lacks the steps for changing the group
of a class when the ratio max_pkt_len/weight of the class changes.
For example, when the last of the following three commands is
executed, the group of class 1:1 is not correctly changed:
tc disc add dev XXX root handle 1: qfq
tc class add dev XXX parent 1: qfq classid 1:1 weight 1
tc class change dev XXX parent 1: classid 1:1 qfq weight 4
Not changing the group of a class does not affect the long-term
bandwidth guaranteed to the class, as the latter is independent of the
maximum packet length, and correctly changes (only) if the weight of
the class changes. In contrast, if the group of the class is not
updated, the class is still guaranteed the short-term bandwidth and
packet delay related to its old group, and not the guarantees that it
should receive according to its new weight and/or maximum packet
length. This may also break service guarantees for other classes.
This patch adds the missing operations.
Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
---
net/sched/sch_qfq.c | 95 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 69 insertions(+), 26 deletions(-)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 9af01f3..e4723d3 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -203,6 +203,34 @@ out:
return index;
}
+/* Length of the next packet (0 if the queue is empty). */
+static unsigned int qdisc_peek_len(struct Qdisc *sch)
+{
+ struct sk_buff *skb;
+
+ skb = sch->ops->peek(sch);
+ return skb ? qdisc_pkt_len(skb) : 0;
+}
+
+static void qfq_deactivate_class(struct qfq_sched *, struct qfq_class *);
+static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
+ unsigned int len);
+
+static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl,
+ u32 lmax, u32 inv_w, int delta_w)
+{
+ int i;
+
+ /* update qfq-specific data */
+ cl->lmax = lmax;
+ cl->inv_w = inv_w;
+ i = qfq_calc_index(cl->inv_w, cl->lmax);
+
+ cl->grp = &q->groups[i];
+
+ q->wsum += delta_w;
+}
+
static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
@@ -250,6 +278,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
lmax = 1UL << QFQ_MTU_SHIFT;
if (cl != NULL) {
+ bool need_reactivation = false;
+
if (tca[TCA_RATE]) {
err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
qdisc_root_sleeping_lock(sch),
@@ -258,12 +288,29 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
return err;
}
- if (inv_w != cl->inv_w) {
- sch_tree_lock(sch);
- q->wsum += delta_w;
- cl->inv_w = inv_w;
- sch_tree_unlock(sch);
+ if (lmax == cl->lmax && inv_w == cl->inv_w)
+ return 0; /* nothing to update */
+
+ i = qfq_calc_index(inv_w, lmax);
+ sch_tree_lock(sch);
+ if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
+ /*
+ * shift cl->F back, to not charge the
+ * class for the not-yet-served head
+ * packet
+ */
+ cl->F = cl->S;
+ /* remove class from its slot in the old group */
+ qfq_deactivate_class(q, cl);
+ need_reactivation = true;
}
+
+ qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
+
+ if (need_reactivation) /* activate in new group */
+ qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
+ sch_tree_unlock(sch);
+
return 0;
}
@@ -273,11 +320,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
cl->refcnt = 1;
cl->common.classid = classid;
- cl->lmax = lmax;
- cl->inv_w = inv_w;
- i = qfq_calc_index(cl->inv_w, cl->lmax);
- cl->grp = &q->groups[i];
+ qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
cl->qdisc = qdisc_create_dflt(sch->dev_queue,
&pfifo_qdisc_ops, classid);
@@ -294,7 +338,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
return err;
}
}
- q->wsum += weight;
sch_tree_lock(sch);
qdisc_class_hash_insert(&q->clhash, &cl->common);
@@ -711,15 +754,6 @@ static void qfq_update_eligible(struct qfq_sched *q, u64 old_V)
}
}
-/* What is length of next packet in queue (0 if queue is empty) */
-static unsigned int qdisc_peek_len(struct Qdisc *sch)
-{
- struct sk_buff *skb;
-
- skb = sch->ops->peek(sch);
- return skb ? qdisc_pkt_len(skb) : 0;
-}
-
/*
* Updates the class, returns true if also the group needs to be updated.
*/
@@ -843,11 +877,8 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
struct qfq_sched *q = qdisc_priv(sch);
- struct qfq_group *grp;
struct qfq_class *cl;
int err;
- u64 roundedS;
- int s;
cl = qfq_classify(skb, sch, &err);
if (cl == NULL) {
@@ -876,11 +907,25 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
return err;
/* If reach this point, queue q was idle */
- grp = cl->grp;
+ qfq_activate_class(q, cl, qdisc_pkt_len(skb));
+
+ return err;
+}
+
+/*
+ * Handle class switch from idle to backlogged.
+ */
+static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
+ unsigned int pkt_len)
+{
+ struct qfq_group *grp = cl->grp;
+ u64 roundedS;
+ int s;
+
qfq_update_start(q, cl);
/* compute new finish time and rounded start. */
- cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w;
+ cl->F = cl->S + (u64)pkt_len * cl->inv_w;
roundedS = qfq_round_down(cl->S, grp->slot_shift);
/*
@@ -917,8 +962,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
skip_update:
qfq_slot_insert(grp, cl, roundedS);
-
- return err;
}
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH net-next,1/1] hyperv: Move wait completion msg code into rndis_filter_halt_device()
From: Haiyang Zhang @ 2012-08-05 19:16 UTC (permalink / raw)
To: David Miller
Cc: olaf@aepfle.de, netdev@vger.kernel.org, jasowang@redhat.com,
linux-kernel@vger.kernel.org, devel@linuxdriverproject.org
In-Reply-To: <20120803.165212.106382119661240198.davem@davemloft.net>
> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Friday, August 03, 2012 7:52 PM
> To: Haiyang Zhang
> Cc: netdev@vger.kernel.org; KY Srinivasan; olaf@aepfle.de;
> jasowang@redhat.com; linux-kernel@vger.kernel.org;
> devel@linuxdriverproject.org
> Subject: Re: [PATCH net-next,1/1] hyperv: Move wait completion msg code
> into rndis_filter_halt_device()
>
> From: Haiyang Zhang <haiyangz@microsoft.com>
> Date: Fri, 3 Aug 2012 12:32:18 -0700
>
> > We need to wait for send_completion msg before put_rndis_request() at
> > the end of rndis_filter_halt_device(). Otherwise,
> > netvsc_send_completion() may reference freed memory which is
> overwritten, and cause panic.
> >
> > Reported-by: Long Li <longli@microsoft.com>
> > Reported-by: Jason Wang <jasowang@redhat.com>
> > Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
>
> This is a bug fix, so applied to 'net'. Please target your patches properly.
>
> Don't just be afraid that I'll reject the patch if you target it at 'net', and
> therefore just target everything at 'net-next'. That is certainly worse.
I see.
Thanks,
- Haiyang
^ permalink raw reply
* Re: [PATCH V2 09/12] net/eipoib: Add main driver functionality
From: Michael S. Tsirkin @ 2012-08-05 18:50 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Or Gerlitz, davem, roland, netdev, ali, sean.hefty, Erez Shitrit
In-Reply-To: <87boitz044.fsf@xmission.com>
On Thu, Aug 02, 2012 at 10:15:23AM -0700, Eric W. Biederman wrote:
> Or Gerlitz <ogerlitz@mellanox.com> writes:
>
> > From: Erez Shitrit <erezsh@mellanox.co.il>
> >
> > The eipoib driver provides a standard Ethernet netdevice over
> > the InfiniBand IPoIB interface .
> >
> > Some services can run only on top of Ethernet L2 interfaces, and cannot be
> > bound to an IPoIB interface. With this new driver, these services can run
> > seamlessly.
>
> Do I read this code correctly that what you are doing is not tunneling
> ethernet over IB but instead you are removing an ethernet header and
> replacing it with an IB header?
>
> Do I also read this code correctly if you can't find your destination
> mac address in your ""neighbor table"" you do a normal IPoIB arp
> for the infiniband GUID?
>
> Do I read this right that if presented with a non-IPv4 or ARP packet
> this code will do something undefined and unpredictable?
>
> Maybe this makes some sense but just skimming it looks like you
> are trying to force a square peg into a round hole resulting in
> some weird code and some very weird maintainability issues.
>
> I am honestly surprised at this approach. I would think it would be
> faster and simpler to run an IB queue pair directly to the hypervisor or
> possibly even the guest operating system bypassing the kernel and doing
> all of this translation in userspace.
>
> Eric
I'm on vacation and I have not looked at the patches, at Erez' request,
just reacting to the presentation and the discussion.
Bypassing the kernel has its own set of issues, not the
least of which is the need to lock all of guest memory which breaks
overcommit. Running an IB queue pair directly to the hypervisor
will also break live migration.
Another problem with exposing IB to guests has to do with the fact that
IB addresses such as combinations of LIDs, GIDs and QPNs to best of my
knowledge do not support soft hardware address setting, which interferes
with live migration.
So it seems that a sane solution would involve an extra level of
indirection, with guest addresses being translated to host IB addresses.
As long as you do this, maybe using an ethernet frame format makes
sense.
So far the things that make sense. Here are some that don't, to me:
- Is a pdf presentation all you have in terms of documentation?
We are talking communication protocols here - I would expect a
proper spec, and some effort to standardize, otherwise where's the
guarantee it won't change in an incompatible way?
Other things that I would expect to be addressed in such a spec is
interaction with other IPoIB features, such as connected
mode, checksum offloading etc, and IB features such as multipath etc.
- The way you encode LID/QPN in the MAC seems questionable. IIRC there's
more to IB addressing than just the LID. Since everyone on the subnet
need access to this translation, I think it makes sense to store it in
the SM. I think this would also obviate some IPv4 specific hacks
in kernel.
- IGMP/MAC snooping in a driver is just too hairy.
As you point out, bridge currently needs the uplink in promisc mode.
I don't think a driver should work around that limitation.
For some setups, it might be interesting to remove the
promisc mode requirement, failing that,
I think you could use macvtap passthrough.
- Currently migration works without host kernel help, would be
preferable to keep it that way.
Hope this helps,
MST
> --
> 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: CPU: 0 Not tainted (3.1.9+ #1) when ifconfig rose0 down
From: Eric W. Biederman @ 2012-08-05 17:23 UTC (permalink / raw)
To: Bernard Pidoux; +Cc: folkert, linux-hams, Linux Netdev List
In-Reply-To: <501E9DFD.4040301@free.fr>
Bernard Pidoux <bernard.pidoux@free.fr> writes:
> Thanks for suggesting a bissect. However I guess that this bug has always been
> there !
One thing that has changed recently is I modified
unregister_netdev_notifier to create synthetic events so drivers don't
need a separate network device tear down path in module unload.
For rose it looks like this has triggered latent bugs.
> I am not professionaly involved in programming, however I committed a few
> patches for ROSE, AX.25 and NetRom modules since a few years.
>
> I reactivated netconfig and here is the report showing that kernel panic occurs
> when rose_device_event is triggered when issuing command
> ifconfig rose0 down
Oh ouch! This is from an ioctl not even at module unload time.
> [ 1215.153302] rose_kill_by_device() rose->neighbour->use 0
> [ 1215.153316] BUG: unable to handle kernel NULL pointer dereference at
> 000000000000002a
> [ 1215.153321] IP: [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 [rose]
> [ 1215.153333] PGD 36340067 PUD 359fa067 PMD 0
> [ 1215.153338] Oops: 0002 [#1] SMP
> [ 1215.153343] CPU 1
> [ 1215.153344] Modules linked in: af_packet rose mkiss ax25 nfsd exportfs nfs
> nfs_acl auth_rpcgss fscache lockd sunrpc netconsole configfs bnep bluetooth
> rfkill snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_hwdep snd_pcm
> snd_page_alloc snd_timer snd i82975x_edac soundcore e1000e ppdev parport_pc
> parport edac_core iTCO_wdt iTCO_vendor_support serio_raw i2c_i801 processor
> coretemp evdev ipv6 autofs4 usbhid hid ext4 crc16 jbd2 sd_mod crc_t10dif
> firewire_ohci firewire_core ehci_hcd crc_itu_t uhci_hcd usbcore usb_common
> nouveau button video mxm_wmi wmi i2c_algo_bit drm_kms_helper ttm drm i2c_core
> ahci libahci ata_piix pata_marvell libata scsi_mod [last unloaded: microcode]
> [ 1215.153395]
> [ 1215.153398] Pid: 18637, comm: ifconfig Not tainted 3.4.7 #8 /D975XBX2
> [ 1215.153404] RIP: 0010:[<ffffffffa065e37d>] [<ffffffffa065e37d>]
> rose_device_event+0x11d/0x160 [rose]
> [ 1215.153411] RSP: 0000:ffff880035271ca8 EFLAGS: 00010296
> [ 1215.153414] RAX: 0000000000000000 RBX: ffff88003d0c2838 RCX: 0000000230924000
> [ 1215.153417] RDX: 0000000000000002 RSI: 0000000000000001 RDI: ffffffffa0665f28
> [ 1215.153420] RBP: ffff880035271cb8 R08: 0000000000000002 R09: 0000000000000000
> [ 1215.153422] R10: 0000000000000003 R11: 0000000000000000 R12: ffff88003a9e1000
> [ 1215.153425] R13: 00000000fffffff1 R14: ffffffffa05b0000 R15: 0000000000000000
> [ 1215.153429] FS: 00007fb7a318f700(0000) GS:ffff88003fa80000(0000)
> knlGS:0000000000000000
> [ 1215.153433] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [ 1215.153435] CR2: 000000000000002a CR3: 00000000393fd000 CR4: 00000000000007e0
> [ 1215.153438] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 1215.153441] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 1215.153445] Process ifconfig (pid: 18637, threadinfo ffff880035270000, task
> ffff88003f5f5d90)
> [ 1215.153448] Stack:
> [ 1215.153450] 0000000000000002 ffff88003a9e1000 ffff880035271cf8
> ffffffff8146d86d
> [ 1215.153455] ffff880036040d00 0000000000000002 ffff88003a9e1000
> 0000000000000000
> [ 1215.153459] 00000000ffffff9d 0000000000000000 ffff880035271d08
> ffffffff8107a2b6
> [ 1215.153464] Call Trace:
> [ 1215.153470] [<ffffffff8146d86d>] notifier_call_chain+0x4d/0x70
> [ 1215.153476] [<ffffffff8107a2b6>] raw_notifier_call_chain+0x16/0x20
> [ 1215.153483] [<ffffffff81395136>] call_netdevice_notifiers+0x36/0x60
> [ 1215.153487] [<ffffffff8139b9ea>] __dev_notify_flags+0x6a/0x90
> [ 1215.153491] [<ffffffff8139ba55>] dev_change_flags+0x45/0x70
> [ 1215.153496] [<ffffffff81403aed>] devinet_ioctl+0x61d/0x7b0
> [ 1215.153500] [<ffffffff81403f05>] inet_ioctl+0x75/0x90
> [ 1215.153505] [<ffffffff8137fbd0>] sock_do_ioctl+0x30/0x70
> [ 1215.153509] [<ffffffff8137fc89>] sock_ioctl+0x79/0x2f0
> [ 1215.153514] [<ffffffff811829d8>] do_vfs_ioctl+0x98/0x560
> [ 1215.153517] [<ffffffff81182f31>] sys_ioctl+0x91/0xa0
> [ 1215.153522] [<ffffffff81471b39>] system_call_fastpath+0x16/0x1b
> [ 1215.153525] Code: e0 5b 41 5c 31 c0 5d c3 48 8d 7b c8 31 c9 ba 09 00 00 00 be
> 65 00 00 00 e8 a1 5c 00 00 48 8b 83 b8 04 00 00 48 c7 c7 28 5f 66 a0 <66> 83 68
> 2a 01 48 8b 83 b8 04 00 00 0f b7 70 2a 31 c0 e8 d4 10
> [ 1215.153561] RIP [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 [rose]
> [ 1215.153567] RSP <ffff880035271ca8>
> [ 1215.153569] CR2: 000000000000002a
> [ 1215.177577] ---[ end trace d23a7ddff228876c ]---
> [ 1215.177589] Kernel panic - not syncing: Fatal exception in interrupt
> [ 1215.177662] panic occurred, switching back to text console
> [ 1215.177717] Rebooting in 60 seconds..
>
> I inserted some printk into rose_device_event() and commented calls to
> subroutines.
> Without calling subroutines, there is no more kernel panic.
> Same results when replacing rose_kill_by_device() in net/rose/af_rose.c,
> rose_link_device_down() and rose_rt_device() in
> net/rose_route.c by a dummy functions with just a printk inside.
>
> I am glad that I found make parameters that shorten the debugging
> cycle :
>
> make modules SUBDIRS=net/rose
> make modules_install SUBDIRS=net/rose
>
> Now I have to go further into each subroutines step by step in order to find out
> the falty code !
Argh inline functions obscuring the backtraces again.
If you are any good at reading assembly you might be able to cut the
tracing time down by using gdb to get a disassembly and looking in the
disassembly.
Although in something easily reproducible what I tend to do is I have
a printk that does.
printk(KERN_EMERG "@%s.%s.%d\n", __FILE__, __func__, __LINE__);
Which I sprinkle all over the code so I know where I fail, and don't
need to cycle too many times.
Sometimes it can be productive to use kvm or a second machine so your
cycle times aren't as long.
In any event I wish you luck tracking this down.
Eric
^ permalink raw reply
* Re: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Mathieu Desnoyers @ 2012-08-05 17:12 UTC (permalink / raw)
To: Sasha Levin
Cc: Steven Rostedt, torvalds, tj, akpm, linux-kernel, linux-mm,
paul.gortmaker, davem, mingo, ebiederm, aarcange, ericvh, netdev,
Lai Jiangshan, Paul E. McKenney
In-Reply-To: <501EA749.9060400@gmail.com>
* Sasha Levin (levinsasha928@gmail.com) wrote:
[...]
> > Other than that, it looks good!
> >
> > Thanks!
> >
> > Mathieu
> >
>
> Thanks for the review Mathieu!
No problem! By the way, if you want to have a look at another hash table
API for ideas, here is the RCU lock-free hash table API, within the
Userspace RCU tree:
from git://git.lttng.org/userspace-rcu.git
branch: master
API: urcu/rculfhash.h
core code: rculfhash.c
hash table index memory management:
rculfhash-mm-chunk.c, rculfhash-mm-mmap.c, rculfhash-mm-order.c
The git tree is down today due to electrical maintenance, so I am
appending the hash table API below.
#ifndef _URCU_RCULFHASH_H
#define _URCU_RCULFHASH_H
/*
* urcu/rculfhash.h
*
* Userspace RCU library - Lock-Free RCU Hash Table
*
* Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
* Copyright 2011 - Lai Jiangshan <laijs@cn.fujitsu.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Include this file _after_ including your URCU flavor.
*/
#include <stdint.h>
#include <urcu/compiler.h>
#include <urcu-call-rcu.h>
#include <urcu-flavor.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* cds_lfht_node: Contains the next pointers and reverse-hash
* value required for lookup and traversal of the hash table.
*
* struct cds_lfht_node should be aligned on 8-bytes boundaries because
* the three lower bits are used as flags. It is worth noting that the
* information contained within these three bits could be represented on
* two bits by re-using the same bit for REMOVAL_OWNER_FLAG and
* BUCKET_FLAG. This can be done if we ensure that no iterator nor
* updater check the BUCKET_FLAG after it detects that the REMOVED_FLAG
* is set. Given the minimum size of struct cds_lfht_node is 8 bytes on
* 32-bit architectures, we choose to go for simplicity and reserve
* three bits.
*
* struct cds_lfht_node can be embedded into a structure (as a field).
* caa_container_of() can be used to get the structure from the struct
* cds_lfht_node after a lookup.
*
* The structure which embeds it typically holds the key (or key-value
* pair) of the object. The caller code is responsible for calculation
* of the hash value for cds_lfht APIs.
*/
struct cds_lfht_node {
struct cds_lfht_node *next; /* ptr | REMOVAL_OWNER_FLAG | BUCKET_FLAG | REMOVED_FLAG */
unsigned long reverse_hash;
} __attribute__((aligned(8)));
/* cds_lfht_iter: Used to track state while traversing a hash chain. */
struct cds_lfht_iter {
struct cds_lfht_node *node, *next;
};
static inline
struct cds_lfht_node *cds_lfht_iter_get_node(struct cds_lfht_iter *iter)
{
return iter->node;
}
struct cds_lfht;
/*
* Caution !
* Ensure reader and writer threads are registered as urcu readers.
*/
typedef int (*cds_lfht_match_fct)(struct cds_lfht_node *node, const void *key);
/*
* cds_lfht_node_init - initialize a hash table node
* @node: the node to initialize.
*
* This function is kept to be eventually used for debugging purposes
* (detection of memory corruption).
*/
static inline
void cds_lfht_node_init(struct cds_lfht_node *node)
{
}
/*
* Hash table creation flags.
*/
enum {
CDS_LFHT_AUTO_RESIZE = (1U << 0),
CDS_LFHT_ACCOUNTING = (1U << 1),
};
struct cds_lfht_mm_type {
struct cds_lfht *(*alloc_cds_lfht)(unsigned long min_nr_alloc_buckets,
unsigned long max_nr_buckets);
void (*alloc_bucket_table)(struct cds_lfht *ht, unsigned long order);
void (*free_bucket_table)(struct cds_lfht *ht, unsigned long order);
struct cds_lfht_node *(*bucket_at)(struct cds_lfht *ht,
unsigned long index);
};
extern const struct cds_lfht_mm_type cds_lfht_mm_order;
extern const struct cds_lfht_mm_type cds_lfht_mm_chunk;
extern const struct cds_lfht_mm_type cds_lfht_mm_mmap;
/*
* _cds_lfht_new - API used by cds_lfht_new wrapper. Do not use directly.
*/
struct cds_lfht *_cds_lfht_new(unsigned long init_size,
unsigned long min_nr_alloc_buckets,
unsigned long max_nr_buckets,
int flags,
const struct cds_lfht_mm_type *mm,
const struct rcu_flavor_struct *flavor,
pthread_attr_t *attr);
/*
* cds_lfht_new - allocate a hash table.
* @init_size: number of buckets to allocate initially. Must be power of two.
* @min_nr_alloc_buckets: the minimum number of allocated buckets.
* (must be power of two)
* @max_nr_buckets: the maximum number of hash table buckets allowed.
* (must be power of two)
* @flags: hash table creation flags (can be combined with bitwise or: '|').
* 0: no flags.
* CDS_LFHT_AUTO_RESIZE: automatically resize hash table.
* CDS_LFHT_ACCOUNTING: count the number of node addition
* and removal in the table
* @attr: optional resize worker thread attributes. NULL for default.
*
* Return NULL on error.
* Note: the RCU flavor must be already included before the hash table header.
*
* The programmer is responsible for ensuring that resize operation has a
* priority equal to hash table updater threads. It should be performed by
* specifying the appropriate priority in the pthread "attr" argument, and,
* for CDS_LFHT_AUTO_RESIZE, by ensuring that call_rcu worker threads also have
* this priority level. Having lower priority for call_rcu and resize threads
* does not pose any correctness issue, but the resize operations could be
* starved by updates, thus leading to long hash table bucket chains.
* Threads calling cds_lfht_new are NOT required to be registered RCU
* read-side threads. It can be called very early. (e.g. before RCU is
* initialized)
*/
static inline
struct cds_lfht *cds_lfht_new(unsigned long init_size,
unsigned long min_nr_alloc_buckets,
unsigned long max_nr_buckets,
int flags,
pthread_attr_t *attr)
{
return _cds_lfht_new(init_size, min_nr_alloc_buckets, max_nr_buckets,
flags, NULL, &rcu_flavor, attr);
}
/*
* cds_lfht_destroy - destroy a hash table.
* @ht: the hash table to destroy.
* @attr: (output) resize worker thread attributes, as received by cds_lfht_new.
* The caller will typically want to free this pointer if dynamically
* allocated. The attr point can be NULL if the caller does not
* need to be informed of the value passed to cds_lfht_new().
*
* Return 0 on success, negative error value on error.
* Threads calling this API need to be registered RCU read-side threads.
*/
int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr);
/*
* cds_lfht_count_nodes - count the number of nodes in the hash table.
* @ht: the hash table.
* @split_count_before: sample the node count split-counter before traversal.
* @count: traverse the hash table, count the number of nodes observed.
* @split_count_after: sample the node count split-counter after traversal.
*
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
*/
void cds_lfht_count_nodes(struct cds_lfht *ht,
long *split_count_before,
unsigned long *count,
long *split_count_after);
/*
* cds_lfht_lookup - lookup a node by key.
* @ht: the hash table.
* @hash: the key hash.
* @match: the key match function.
* @key: the current node key.
* @iter: node, if found (output). *iter->node set to NULL if not found.
*
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* This function acts as a rcu_dereference() to read the node pointer.
*/
void cds_lfht_lookup(struct cds_lfht *ht, unsigned long hash,
cds_lfht_match_fct match, const void *key,
struct cds_lfht_iter *iter);
/*
* cds_lfht_next_duplicate - get the next item with same key, after iterator.
* @ht: the hash table.
* @match: the key match function.
* @key: the current node key.
* @iter: input: current iterator.
* output: node, if found. *iter->node set to NULL if not found.
*
* Uses an iterator initialized by a lookup or traversal. Important: the
* iterator _needs_ to be initialized before calling
* cds_lfht_next_duplicate.
* Sets *iter-node to the following node with same key.
* Sets *iter->node to NULL if no following node exists with same key.
* RCU read-side lock must be held across cds_lfht_lookup and
* cds_lfht_next calls, and also between cds_lfht_next calls using the
* node returned by a previous cds_lfht_next.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* This function acts as a rcu_dereference() to read the node pointer.
*/
void cds_lfht_next_duplicate(struct cds_lfht *ht,
cds_lfht_match_fct match, const void *key,
struct cds_lfht_iter *iter);
/*
* cds_lfht_first - get the first node in the table.
* @ht: the hash table.
* @iter: First node, if exists (output). *iter->node set to NULL if not found.
*
* Output in "*iter". *iter->node set to NULL if table is empty.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* This function acts as a rcu_dereference() to read the node pointer.
*/
void cds_lfht_first(struct cds_lfht *ht, struct cds_lfht_iter *iter);
/*
* cds_lfht_next - get the next node in the table.
* @ht: the hash table.
* @iter: input: current iterator.
* output: next node, if exists. *iter->node set to NULL if not found.
*
* Input/Output in "*iter". *iter->node set to NULL if *iter was
* pointing to the last table node.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* This function acts as a rcu_dereference() to read the node pointer.
*/
void cds_lfht_next(struct cds_lfht *ht, struct cds_lfht_iter *iter);
/*
* cds_lfht_add - add a node to the hash table.
* @ht: the hash table.
* @hash: the key hash.
* @node: the node to add.
*
* This function supports adding redundant keys into the table.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* This function issues a full memory barrier before and after its
* atomic commit.
*/
void cds_lfht_add(struct cds_lfht *ht, unsigned long hash,
struct cds_lfht_node *node);
/*
* cds_lfht_add_unique - add a node to hash table, if key is not present.
* @ht: the hash table.
* @hash: the node's hash.
* @match: the key match function.
* @key: the node's key.
* @node: the node to try adding.
*
* Return the node added upon success.
* Return the unique node already present upon failure. If
* cds_lfht_add_unique fails, the node passed as parameter should be
* freed by the caller. In this case, the caller does NOT need to wait
* for a grace period before freeing the node.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
*
* The semantic of this function is that if only this function is used
* to add keys into the table, no duplicated keys should ever be
* observable in the table. The same guarantee apply for combination of
* add_unique and add_replace (see below).
*
* Upon success, this function issues a full memory barrier before and
* after its atomic commit. Upon failure, this function acts like a
* simple lookup operation: it acts as a rcu_dereference() to read the
* node pointer. The failure case does not guarantee any other memory
* barrier.
*/
struct cds_lfht_node *cds_lfht_add_unique(struct cds_lfht *ht,
unsigned long hash,
cds_lfht_match_fct match,
const void *key,
struct cds_lfht_node *node);
/*
* cds_lfht_add_replace - replace or add a node within hash table.
* @ht: the hash table.
* @hash: the node's hash.
* @match: the key match function.
* @key: the node's key.
* @node: the node to add.
*
* Return the node replaced upon success. If no node matching the key
* was present, return NULL, which also means the operation succeeded.
* This replacement operation should never fail.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* After successful replacement, a grace period must be waited for before
* freeing the memory reserved for the returned node.
*
* The semantic of replacement vs lookups and traversals is the
* following: if lookups and traversals are performed between a key
* unique insertion and its removal, we guarantee that the lookups and
* traversals will always find exactly one instance of the key if it is
* replaced concurrently with the lookups.
*
* Providing this semantic allows us to ensure that replacement-only
* schemes will never generate duplicated keys. It also allows us to
* guarantee that a combination of add_replace and add_unique updates
* will never generate duplicated keys.
*
* This function issues a full memory barrier before and after its
* atomic commit.
*/
struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht,
unsigned long hash,
cds_lfht_match_fct match,
const void *key,
struct cds_lfht_node *node);
/*
* cds_lfht_replace - replace a node pointed to by iter within hash table.
* @ht: the hash table.
* @old_iter: the iterator position of the node to replace.
* @hash: the node's hash.
* @match: the key match function.
* @key: the node's key.
* @new_node: the new node to use as replacement.
*
* Return 0 if replacement is successful, negative value otherwise.
* Replacing a NULL old node or an already removed node will fail with
* -ENOENT.
* If the hash or value of the node to replace and the new node differ,
* this function returns -EINVAL without proceeding to the replacement.
* Old node can be looked up with cds_lfht_lookup and cds_lfht_next.
* RCU read-side lock must be held between lookup and replacement.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* After successful replacement, a grace period must be waited for before
* freeing the memory reserved for the old node (which can be accessed
* with cds_lfht_iter_get_node).
*
* The semantic of replacement vs lookups is the same as
* cds_lfht_add_replace().
*
* Upon success, this function issues a full memory barrier before and
* after its atomic commit. Upon failure, this function does not issue
* any memory barrier.
*/
int cds_lfht_replace(struct cds_lfht *ht,
struct cds_lfht_iter *old_iter,
unsigned long hash,
cds_lfht_match_fct match,
const void *key,
struct cds_lfht_node *new_node);
/*
* cds_lfht_del - remove node pointed to by iterator from hash table.
* @ht: the hash table.
* @node: the node to delete.
*
* Return 0 if the node is successfully removed, negative value
* otherwise.
* Deleting a NULL node or an already removed node will fail with a
* negative value.
* Node can be looked up with cds_lfht_lookup and cds_lfht_next,
* followed by use of cds_lfht_iter_get_node.
* RCU read-side lock must be held between lookup and removal.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* After successful removal, a grace period must be waited for before
* freeing the memory reserved for old node (which can be accessed with
* cds_lfht_iter_get_node).
* Upon success, this function issues a full memory barrier before and
* after its atomic commit. Upon failure, this function does not issue
* any memory barrier.
*/
int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node);
/*
* cds_lfht_is_node_deleted - query whether a node is removed from hash table.
*
* Return non-zero if the node is deleted from the hash table, 0
* otherwise.
* Node can be looked up with cds_lfht_lookup and cds_lfht_next,
* followed by use of cds_lfht_iter_get_node.
* RCU read-side lock must be held between lookup and call to this
* function.
* Call with rcu_read_lock held.
* Threads calling this API need to be registered RCU read-side threads.
* This function does not issue any memory barrier.
*/
int cds_lfht_is_node_deleted(struct cds_lfht_node *node);
/*
* cds_lfht_resize - Force a hash table resize
* @ht: the hash table.
* @new_size: update to this hash table size.
*
* Threads calling this API need to be registered RCU read-side threads.
* This function does not (necessarily) issue memory barriers.
*/
void cds_lfht_resize(struct cds_lfht *ht, unsigned long new_size);
/*
* Note: it is safe to perform element removal (del), replacement, or
* any hash table update operation during any of the following hash
* table traversals.
* These functions act as rcu_dereference() to read the node pointers.
*/
#define cds_lfht_for_each(ht, iter, node) \
for (cds_lfht_first(ht, iter), \
node = cds_lfht_iter_get_node(iter); \
node != NULL; \
cds_lfht_next(ht, iter), \
node = cds_lfht_iter_get_node(iter))
#define cds_lfht_for_each_duplicate(ht, hash, match, key, iter, node) \
for (cds_lfht_lookup(ht, hash, match, key, iter), \
node = cds_lfht_iter_get_node(iter); \
node != NULL; \
cds_lfht_next_duplicate(ht, match, key, iter), \
node = cds_lfht_iter_get_node(iter))
#define cds_lfht_for_each_entry(ht, iter, pos, member) \
for (cds_lfht_first(ht, iter), \
pos = caa_container_of(cds_lfht_iter_get_node(iter), \
__typeof__(*(pos)), member); \
&(pos)->member != NULL; \
cds_lfht_next(ht, iter), \
pos = caa_container_of(cds_lfht_iter_get_node(iter), \
__typeof__(*(pos)), member))
#define cds_lfht_for_each_entry_duplicate(ht, hash, match, key, \
iter, pos, member) \
for (cds_lfht_lookup(ht, hash, match, key, iter), \
pos = caa_container_of(cds_lfht_iter_get_node(iter), \
__typeof__(*(pos)), member); \
&(pos)->member != NULL; \
cds_lfht_next_duplicate(ht, match, key, iter), \
pos = caa_container_of(cds_lfht_iter_get_node(iter), \
__typeof__(*(pos)), member))
#ifdef __cplusplus
}
#endif
#endif /* _URCU_RCULFHASH_H */
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: CPU: 0 Not tainted (3.1.9+ #1) when ifconfig rose0 down
From: Folkert van Heusden @ 2012-08-05 17:08 UTC (permalink / raw)
To: Bernard Pidoux, folkert; +Cc: Eric W. Biederman, linux-hams, Linux Netdev List
Good luck!
I'm to busy myself with debugging the baycom driver.
Can do at most 2 steps a day and it are 15 steps... (54k changesets)
Bernard Pidoux <bernard.pidoux@free.fr> wrote:
>Thanks for suggesting a bissect. However I guess that this bug has
>always been there !
>
>I am not professionaly involved in programming, however I committed a
>few patches for ROSE, AX.25 and NetRom modules since a few years.
>
>I reactivated netconfig and here is the report showing that kernel panic
>occurs when rose_device_event is triggered when issuing command
>ifconfig rose0 down
>
>[ 1215.153302] rose_kill_by_device() rose->neighbour->use 0
>[ 1215.153316] BUG: unable to handle kernel NULL pointer dereference at
>000000000000002a
>[ 1215.153321] IP: [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 [rose]
>[ 1215.153333] PGD 36340067 PUD 359fa067 PMD 0
>[ 1215.153338] Oops: 0002 [#1] SMP
>[ 1215.153343] CPU 1
>[ 1215.153344] Modules linked in: af_packet rose mkiss ax25 nfsd
>exportfs nfs nfs_acl auth_rpcgss fscache lockd sunrpc netconsole
>configfs bnep bluetooth rfkill snd_hda_codec_idt snd_hda_intel
>snd_hda_codec snd_hwdep snd_pcm snd_page_alloc snd_timer snd
>i82975x_edac soundcore e1000e ppdev parport_pc parport edac_core
>iTCO_wdt iTCO_vendor_support serio_raw i2c_i801 processor coretemp evdev
>ipv6 autofs4 usbhid hid ext4 crc16 jbd2 sd_mod crc_t10dif firewire_ohci
>firewire_core ehci_hcd crc_itu_t uhci_hcd usbcore usb_common nouveau
>button video mxm_wmi wmi i2c_algo_bit drm_kms_helper ttm drm i2c_core
>ahci libahci ata_piix pata_marvell libata scsi_mod [last unloaded:
>microcode]
>[ 1215.153395]
>[ 1215.153398] Pid: 18637, comm: ifconfig Not tainted 3.4.7 #8
>/D975XBX2
>[ 1215.153404] RIP: 0010:[<ffffffffa065e37d>] [<ffffffffa065e37d>]
>rose_device_event+0x11d/0x160 [rose]
>[ 1215.153411] RSP: 0000:ffff880035271ca8 EFLAGS: 00010296
>[ 1215.153414] RAX: 0000000000000000 RBX: ffff88003d0c2838 RCX:
>0000000230924000
>[ 1215.153417] RDX: 0000000000000002 RSI: 0000000000000001 RDI:
>ffffffffa0665f28
>[ 1215.153420] RBP: ffff880035271cb8 R08: 0000000000000002 R09:
>0000000000000000
>[ 1215.153422] R10: 0000000000000003 R11: 0000000000000000 R12:
>ffff88003a9e1000
>[ 1215.153425] R13: 00000000fffffff1 R14: ffffffffa05b0000 R15:
>0000000000000000
>[ 1215.153429] FS: 00007fb7a318f700(0000) GS:ffff88003fa80000(0000)
>knlGS:0000000000000000
>[ 1215.153433] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>[ 1215.153435] CR2: 000000000000002a CR3: 00000000393fd000 CR4:
>00000000000007e0
>[ 1215.153438] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
>0000000000000000
>[ 1215.153441] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
>0000000000000400
>[ 1215.153445] Process ifconfig (pid: 18637, threadinfo
>ffff880035270000, task ffff88003f5f5d90)
>[ 1215.153448] Stack:
>[ 1215.153450] 0000000000000002 ffff88003a9e1000 ffff880035271cf8
>ffffffff8146d86d
>[ 1215.153455] ffff880036040d00 0000000000000002 ffff88003a9e1000
>0000000000000000
>[ 1215.153459] 00000000ffffff9d 0000000000000000 ffff880035271d08
>ffffffff8107a2b6
>[ 1215.153464] Call Trace:
>[ 1215.153470] [<ffffffff8146d86d>] notifier_call_chain+0x4d/0x70
>[ 1215.153476] [<ffffffff8107a2b6>] raw_notifier_call_chain+0x16/0x20
>[ 1215.153483] [<ffffffff81395136>] call_netdevice_notifiers+0x36/0x60
>[ 1215.153487] [<ffffffff8139b9ea>] __dev_notify_flags+0x6a/0x90
>[ 1215.153491] [<ffffffff8139ba55>] dev_change_flags+0x45/0x70
>[ 1215.153496] [<ffffffff81403aed>] devinet_ioctl+0x61d/0x7b0
>[ 1215.153500] [<ffffffff81403f05>] inet_ioctl+0x75/0x90
>[ 1215.153505] [<ffffffff8137fbd0>] sock_do_ioctl+0x30/0x70
>[ 1215.153509] [<ffffffff8137fc89>] sock_ioctl+0x79/0x2f0
>[ 1215.153514] [<ffffffff811829d8>] do_vfs_ioctl+0x98/0x560
>[ 1215.153517] [<ffffffff81182f31>] sys_ioctl+0x91/0xa0
>[ 1215.153522] [<ffffffff81471b39>] system_call_fastpath+0x16/0x1b
>[ 1215.153525] Code: e0 5b 41 5c 31 c0 5d c3 48 8d 7b c8 31 c9 ba 09 00
>00 00 be 65 00 00 00 e8 a1 5c 00 00 48 8b 83 b8 04 00 00 48 c7 c7 28 5f
>66 a0 <66> 83 68 2a 01 48 8b 83 b8 04 00 00 0f b7 70 2a 31 c0 e8 d4 10
>[ 1215.153561] RIP [<ffffffffa065e37d>] rose_device_event+0x11d/0x160
>[rose]
>[ 1215.153567] RSP <ffff880035271ca8>
>[ 1215.153569] CR2: 000000000000002a
>[ 1215.177577] ---[ end trace d23a7ddff228876c ]---
>[ 1215.177589] Kernel panic - not syncing: Fatal exception in interrupt
>[ 1215.177662] panic occurred, switching back to text console
>[ 1215.177717] Rebooting in 60 seconds..
>
>I inserted some printk into rose_device_event() and commented calls to
>subroutines.
>Without calling subroutines, there is no more kernel panic.
>Same results when replacing rose_kill_by_device() in net/rose/af_rose.c,
>rose_link_device_down() and rose_rt_device() in
>net/rose_route.c by a dummy functions with just a printk inside.
>
>I am glad that I found make parameters that shorten the debugging
>cycle :
>
>make modules SUBDIRS=net/rose
>make modules_install SUBDIRS=net/rose
>
>Now I have to go further into each subroutines step by step in order to
>find out the falty code !
>
>
>Bernard
>
>
>On 03/08/2012 16:32, folkert wrote:
>>> You might want to simply try moving unregister_netdevice_notifier a bit
>>> earlier in rose_exit and see if that helps. Otherwise I would recommend
>>> instrumenting the code up with some printk so you can understand what
>>> part of unregistration is failing.
>>
>> Or bisect! Give e.g. the oldest 2.6 kernel a try to find a last known
>> good and then do a bisect upto a known bad kernel.
>>
>>
>> Folkert van Heusden
>>
>
^ permalink raw reply
* Re: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Sasha Levin @ 2012-08-05 17:03 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: Steven Rostedt, torvalds, tj, akpm, linux-kernel, linux-mm,
paul.gortmaker, davem, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <20120805163114.GA21768@Krystal>
On 08/05/2012 06:31 PM, Mathieu Desnoyers wrote:
> * Steven Rostedt (rostedt@goodmis.org) wrote:
>> FYI, Mathieu is the author of this file.
>>
>> -- Steve
>>
>>
>> On Fri, 2012-08-03 at 16:23 +0200, Sasha Levin wrote:
>>> Switch tracepoints to use the new hashtable implementation. This reduces the amount of
>>> generic unrelated code in the tracepoints.
>>>
>>> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
>>> ---
>>> kernel/tracepoint.c | 26 +++++++++-----------------
>>> 1 files changed, 9 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
>>> index d96ba22..b5a2650 100644
>>> --- a/kernel/tracepoint.c
>>> +++ b/kernel/tracepoint.c
>>> @@ -26,6 +26,7 @@
>>> #include <linux/slab.h>
>>> #include <linux/sched.h>
>>> #include <linux/static_key.h>
>>> +#include <linux/hashtable.h>
>>>
>>> extern struct tracepoint * const __start___tracepoints_ptrs[];
>>> extern struct tracepoint * const __stop___tracepoints_ptrs[];
>>> @@ -49,8 +50,7 @@ static LIST_HEAD(tracepoint_module_list);
>>> * Protected by tracepoints_mutex.
>>> */
>>> #define TRACEPOINT_HASH_BITS 6
>>> -#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
>>> -static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
>>> +DEFINE_STATIC_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
>
> I wonder why the "static" has been embedded within
> "DEFINE_STATIC_HASHTABLE" ? I'm used to see something similar to:
>
> static DEFINE_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
>
> elsewhere in the kernel (e.g. static DEFINE_PER_CPU(), static
> DEFINE_MUTEX(), etc).
We had to create two different definitions of hashtable, one to be used as static and one to be used in structs. I chose the uglier way of doing it, and Tejun already pointed it out :)
It will be much nicer in the future.
>>>
>>> /*
>>> * Note about RCU :
>>> @@ -191,16 +191,14 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
>>> */
>>> static struct tracepoint_entry *get_tracepoint(const char *name)
>>> {
>>> - struct hlist_head *head;
>>> struct hlist_node *node;
>>> struct tracepoint_entry *e;
>>> u32 hash = jhash(name, strlen(name), 0);
>>>
>>> - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
>>> - hlist_for_each_entry(e, node, head, hlist) {
>>> + hash_for_each_possible(&tracepoint_table, node, e, hlist, hash)
>>> if (!strcmp(name, e->name))
>>> return e;
>>> - }
>>> +
>
> Typically, where there are 2 or more nesting levels, I try to keep the
> outer brackets, even if the 1st level only contain a single statement
> (this is what I did across tracepoint.c). This is especially useful when
> nesting multiple if levels, and ensures the "else" clause match the
> right if. We might want to keep it that way within the file, to ensure
> style consistency.
Roger that, will fix.
> Other than that, it looks good!
>
> Thanks!
>
> Mathieu
>
Thanks for the review Mathieu!
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Mathieu Desnoyers @ 2012-08-05 16:31 UTC (permalink / raw)
To: Steven Rostedt
Cc: Sasha Levin, torvalds, tj, akpm, linux-kernel, linux-mm,
paul.gortmaker, davem, mingo, ebiederm, aarcange, ericvh, netdev
In-Reply-To: <1344126994.27983.116.camel@gandalf.stny.rr.com>
* Steven Rostedt (rostedt@goodmis.org) wrote:
> FYI, Mathieu is the author of this file.
>
> -- Steve
>
>
> On Fri, 2012-08-03 at 16:23 +0200, Sasha Levin wrote:
> > Switch tracepoints to use the new hashtable implementation. This reduces the amount of
> > generic unrelated code in the tracepoints.
> >
> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> > ---
> > kernel/tracepoint.c | 26 +++++++++-----------------
> > 1 files changed, 9 insertions(+), 17 deletions(-)
> >
> > diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
> > index d96ba22..b5a2650 100644
> > --- a/kernel/tracepoint.c
> > +++ b/kernel/tracepoint.c
> > @@ -26,6 +26,7 @@
> > #include <linux/slab.h>
> > #include <linux/sched.h>
> > #include <linux/static_key.h>
> > +#include <linux/hashtable.h>
> >
> > extern struct tracepoint * const __start___tracepoints_ptrs[];
> > extern struct tracepoint * const __stop___tracepoints_ptrs[];
> > @@ -49,8 +50,7 @@ static LIST_HEAD(tracepoint_module_list);
> > * Protected by tracepoints_mutex.
> > */
> > #define TRACEPOINT_HASH_BITS 6
> > -#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
> > -static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
> > +DEFINE_STATIC_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
I wonder why the "static" has been embedded within
"DEFINE_STATIC_HASHTABLE" ? I'm used to see something similar to:
static DEFINE_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
elsewhere in the kernel (e.g. static DEFINE_PER_CPU(), static
DEFINE_MUTEX(), etc).
> >
> > /*
> > * Note about RCU :
> > @@ -191,16 +191,14 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
> > */
> > static struct tracepoint_entry *get_tracepoint(const char *name)
> > {
> > - struct hlist_head *head;
> > struct hlist_node *node;
> > struct tracepoint_entry *e;
> > u32 hash = jhash(name, strlen(name), 0);
> >
> > - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
> > - hlist_for_each_entry(e, node, head, hlist) {
> > + hash_for_each_possible(&tracepoint_table, node, e, hlist, hash)
> > if (!strcmp(name, e->name))
> > return e;
> > - }
> > +
Typically, where there are 2 or more nesting levels, I try to keep the
outer brackets, even if the 1st level only contain a single statement
(this is what I did across tracepoint.c). This is especially useful when
nesting multiple if levels, and ensures the "else" clause match the
right if. We might want to keep it that way within the file, to ensure
style consistency.
Other than that, it looks good!
Thanks!
Mathieu
> > return NULL;
> > }
> >
> > @@ -210,19 +208,13 @@ static struct tracepoint_entry *get_tracepoint(const char *name)
> > */
> > static struct tracepoint_entry *add_tracepoint(const char *name)
> > {
> > - struct hlist_head *head;
> > - struct hlist_node *node;
> > struct tracepoint_entry *e;
> > size_t name_len = strlen(name) + 1;
> > u32 hash = jhash(name, name_len-1, 0);
> >
> > - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
> > - hlist_for_each_entry(e, node, head, hlist) {
> > - if (!strcmp(name, e->name)) {
> > - printk(KERN_NOTICE
> > - "tracepoint %s busy\n", name);
> > - return ERR_PTR(-EEXIST); /* Already there */
> > - }
> > + if (get_tracepoint(name)) {
> > + printk(KERN_NOTICE "tracepoint %s busy\n", name);
> > + return ERR_PTR(-EEXIST); /* Already there */
> > }
> > /*
> > * Using kmalloc here to allocate a variable length element. Could
> > @@ -234,7 +226,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
> > memcpy(&e->name[0], name, name_len);
> > e->funcs = NULL;
> > e->refcount = 0;
> > - hlist_add_head(&e->hlist, head);
> > + hash_add(&tracepoint_table, &e->hlist, hash);
> > return e;
> > }
> >
> > @@ -244,7 +236,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
> > */
> > static inline void remove_tracepoint(struct tracepoint_entry *e)
> > {
> > - hlist_del(&e->hlist);
> > + hash_del(&e->hlist);
> > kfree(e);
> > }
> >
>
>
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: CPU: 0 Not tainted (3.1.9+ #1) when ifconfig rose0 down
From: Bernard Pidoux @ 2012-08-05 16:23 UTC (permalink / raw)
To: folkert; +Cc: Eric W. Biederman, linux-hams, Linux Netdev List
In-Reply-To: <20120803143200.GE10211@belle.intranet.vanheusden.com>
Thanks for suggesting a bissect. However I guess that this bug has
always been there !
I am not professionaly involved in programming, however I committed a
few patches for ROSE, AX.25 and NetRom modules since a few years.
I reactivated netconfig and here is the report showing that kernel panic
occurs when rose_device_event is triggered when issuing command
ifconfig rose0 down
[ 1215.153302] rose_kill_by_device() rose->neighbour->use 0
[ 1215.153316] BUG: unable to handle kernel NULL pointer dereference at
000000000000002a
[ 1215.153321] IP: [<ffffffffa065e37d>] rose_device_event+0x11d/0x160 [rose]
[ 1215.153333] PGD 36340067 PUD 359fa067 PMD 0
[ 1215.153338] Oops: 0002 [#1] SMP
[ 1215.153343] CPU 1
[ 1215.153344] Modules linked in: af_packet rose mkiss ax25 nfsd
exportfs nfs nfs_acl auth_rpcgss fscache lockd sunrpc netconsole
configfs bnep bluetooth rfkill snd_hda_codec_idt snd_hda_intel
snd_hda_codec snd_hwdep snd_pcm snd_page_alloc snd_timer snd
i82975x_edac soundcore e1000e ppdev parport_pc parport edac_core
iTCO_wdt iTCO_vendor_support serio_raw i2c_i801 processor coretemp evdev
ipv6 autofs4 usbhid hid ext4 crc16 jbd2 sd_mod crc_t10dif firewire_ohci
firewire_core ehci_hcd crc_itu_t uhci_hcd usbcore usb_common nouveau
button video mxm_wmi wmi i2c_algo_bit drm_kms_helper ttm drm i2c_core
ahci libahci ata_piix pata_marvell libata scsi_mod [last unloaded:
microcode]
[ 1215.153395]
[ 1215.153398] Pid: 18637, comm: ifconfig Not tainted 3.4.7 #8
/D975XBX2
[ 1215.153404] RIP: 0010:[<ffffffffa065e37d>] [<ffffffffa065e37d>]
rose_device_event+0x11d/0x160 [rose]
[ 1215.153411] RSP: 0000:ffff880035271ca8 EFLAGS: 00010296
[ 1215.153414] RAX: 0000000000000000 RBX: ffff88003d0c2838 RCX:
0000000230924000
[ 1215.153417] RDX: 0000000000000002 RSI: 0000000000000001 RDI:
ffffffffa0665f28
[ 1215.153420] RBP: ffff880035271cb8 R08: 0000000000000002 R09:
0000000000000000
[ 1215.153422] R10: 0000000000000003 R11: 0000000000000000 R12:
ffff88003a9e1000
[ 1215.153425] R13: 00000000fffffff1 R14: ffffffffa05b0000 R15:
0000000000000000
[ 1215.153429] FS: 00007fb7a318f700(0000) GS:ffff88003fa80000(0000)
knlGS:0000000000000000
[ 1215.153433] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 1215.153435] CR2: 000000000000002a CR3: 00000000393fd000 CR4:
00000000000007e0
[ 1215.153438] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 1215.153441] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7:
0000000000000400
[ 1215.153445] Process ifconfig (pid: 18637, threadinfo
ffff880035270000, task ffff88003f5f5d90)
[ 1215.153448] Stack:
[ 1215.153450] 0000000000000002 ffff88003a9e1000 ffff880035271cf8
ffffffff8146d86d
[ 1215.153455] ffff880036040d00 0000000000000002 ffff88003a9e1000
0000000000000000
[ 1215.153459] 00000000ffffff9d 0000000000000000 ffff880035271d08
ffffffff8107a2b6
[ 1215.153464] Call Trace:
[ 1215.153470] [<ffffffff8146d86d>] notifier_call_chain+0x4d/0x70
[ 1215.153476] [<ffffffff8107a2b6>] raw_notifier_call_chain+0x16/0x20
[ 1215.153483] [<ffffffff81395136>] call_netdevice_notifiers+0x36/0x60
[ 1215.153487] [<ffffffff8139b9ea>] __dev_notify_flags+0x6a/0x90
[ 1215.153491] [<ffffffff8139ba55>] dev_change_flags+0x45/0x70
[ 1215.153496] [<ffffffff81403aed>] devinet_ioctl+0x61d/0x7b0
[ 1215.153500] [<ffffffff81403f05>] inet_ioctl+0x75/0x90
[ 1215.153505] [<ffffffff8137fbd0>] sock_do_ioctl+0x30/0x70
[ 1215.153509] [<ffffffff8137fc89>] sock_ioctl+0x79/0x2f0
[ 1215.153514] [<ffffffff811829d8>] do_vfs_ioctl+0x98/0x560
[ 1215.153517] [<ffffffff81182f31>] sys_ioctl+0x91/0xa0
[ 1215.153522] [<ffffffff81471b39>] system_call_fastpath+0x16/0x1b
[ 1215.153525] Code: e0 5b 41 5c 31 c0 5d c3 48 8d 7b c8 31 c9 ba 09 00
00 00 be 65 00 00 00 e8 a1 5c 00 00 48 8b 83 b8 04 00 00 48 c7 c7 28 5f
66 a0 <66> 83 68 2a 01 48 8b 83 b8 04 00 00 0f b7 70 2a 31 c0 e8 d4 10
[ 1215.153561] RIP [<ffffffffa065e37d>] rose_device_event+0x11d/0x160
[rose]
[ 1215.153567] RSP <ffff880035271ca8>
[ 1215.153569] CR2: 000000000000002a
[ 1215.177577] ---[ end trace d23a7ddff228876c ]---
[ 1215.177589] Kernel panic - not syncing: Fatal exception in interrupt
[ 1215.177662] panic occurred, switching back to text console
[ 1215.177717] Rebooting in 60 seconds..
I inserted some printk into rose_device_event() and commented calls to
subroutines.
Without calling subroutines, there is no more kernel panic.
Same results when replacing rose_kill_by_device() in net/rose/af_rose.c,
rose_link_device_down() and rose_rt_device() in
net/rose_route.c by a dummy functions with just a printk inside.
I am glad that I found make parameters that shorten the debugging
cycle :
make modules SUBDIRS=net/rose
make modules_install SUBDIRS=net/rose
Now I have to go further into each subroutines step by step in order to
find out the falty code !
Bernard
On 03/08/2012 16:32, folkert wrote:
>> You might want to simply try moving unregister_netdevice_notifier a bit
>> earlier in rose_exit and see if that helps. Otherwise I would recommend
>> instrumenting the code up with some printk so you can understand what
>> part of unregistration is failing.
>
> Or bisect! Give e.g. the oldest 2.6 kernel a try to find a last known
> good and then do a bisect upto a known bad kernel.
>
>
> Folkert van Heusden
>
^ permalink raw reply
* [PATCH 6/6] drivers/atm/iphase.c: fix error return code
From: Julia Lawall @ 2012-08-05 9:52 UTC (permalink / raw)
To: Chas Williams
Cc: kernel-janitors, linux-atm-general, netdev, linux-kernel,
Julia Lawall
In-Reply-To: <1344160356-387-1-git-send-email-Julia.Lawall@lip6.fr>
From: Julia Lawall <julia@diku.dk>
Convert a 0 error return code to a negative one, as returned elsewhere in the
function.
A simplified version of the semantic match that finds this problem is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
identifier ret;
expression e,e1,e2,e3,e4,x;
@@
(
if (\(ret != 0\|ret < 0\) || ...) { ... return ...; }
|
ret = 0
)
... when != ret = e1
*x = \(kmalloc\|kzalloc\|kcalloc\|devm_kzalloc\|ioremap\|ioremap_nocache\|devm_ioremap\|devm_ioremap_nocache\)(...);
... when != x = e2
when != ret = e3
*if (x == NULL || ...)
{
... when != ret = e4
* return ret;
}
// </smpl>
Signed-off-by: Julia Lawall <julia@diku.dk>
---
drivers/atm/iphase.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index d438601..96cce6d 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -2362,7 +2362,7 @@ static int __devinit ia_init(struct atm_dev *dev)
{
printk(DEV_LABEL " (itf %d): can't set up page mapping\n",
dev->number);
- return error;
+ return -ENOMEM;
}
IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n",
dev->number, iadev->pci->revision, base, iadev->irq);)
^ permalink raw reply related
* Re: Huge performance degradation for UDP between 2.4.17 and 2.6
From: Eric Dumazet @ 2012-08-05 8:28 UTC (permalink / raw)
To: LEROY christophe; +Cc: linux-kernel, netdev
In-Reply-To: <501E2BC5.5020709@c-s.fr>
On Sun, 2012-08-05 at 10:16 +0200, LEROY christophe wrote:
> Le 02/08/2012 16:13, Eric Dumazet a écrit :
> > On Thu, 2012-08-02 at 14:27 +0200, leroy christophe wrote:
> >> Hi
> >>
> >> I'm having a big issue with UDP. Using a powerpc board (MPC860).
> >>
> >> With our board running kernel 2.4.17, I'm able to send 160000 voice
> >> packets (UDP, 96 bytes per packet) in 11 seconds.
> >> With the same board running either Kernel 2.6.35.14 or Kernel 3.4.7, I
> >> need 55 seconds to send the same amount of packets.
> >>
> >>
> >> Is there anything to tune in order to get same output rate as with
> >> Kernel 2.4 ?
> > kernel size is probably too big for your old / slow cpu.
> >
> > Maybe you added too many features on your 3.4.7 kernel. (netfilter ?
> > SLUB debugging ...)
> >
> > Its hard to say, 2.4.17 had less features and was faster.
> >
>
> Thanks for your answer.
> Yes I have netfilter as I need it. However, I tried without it and still
> need about 37 seconds to send the 160000 packets I was sending in 11
> seconds with 2.4.17
>
> I don't think there is any problem with size of the kernel. I still have
> plenty of memory available.
>
I believe you misunderstood me.
I was referring to cpu caches ( dcache & icache )
> All debugging is turned off, and I'm not using SLUB but SLOB.
> I have 32Mbytes of RAM. Would SLUB be more performant than SLOB ?
I never used SLOB I cannot comment
Please provide (on 3.4.7)
cat /proc/cpuinfo
lsmod
dmesg
^ permalink raw reply
* Re: Bridge extensions to iproute2
From: Maciej Żenczykowski @ 2012-08-05 7:27 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Stephen Hemminger, Linux NetDev, David Miller
In-Reply-To: <meqjoqmsb19c7jsv7pbldsjc.1344134703305@email.android.com>
Yes, there really isn't much reason for bridge configuration to be a
separate package than iproute, seeing how there's vlan/veth etc
configuration built into 'ip'
On Sat, Aug 4, 2012 at 7:45 PM, Stephen Hemminger
<stephen.hemminger@vyatta.com> wrote:
> There is barely any overlap between bridge-utils and iproute2.
> I was thinking of making a script 'brctl' that does same thing as
> old utility but using new netlink based commands.
>
^ permalink raw reply
* [PATCH net-next] net: reorganize IP MIB values
From: Eric Dumazet @ 2012-08-05 6:33 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
Reduce IP latencies by placing hot MIB IP fields in a single cache line.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/linux/snmp.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index 00bc189..aa02b9e 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -18,7 +18,14 @@
enum
{
IPSTATS_MIB_NUM = 0,
+/* frequently written fields in fast path, kept in same cache line */
IPSTATS_MIB_INPKTS, /* InReceives */
+ IPSTATS_MIB_INOCTETS, /* InOctets */
+ IPSTATS_MIB_INDELIVERS, /* InDelivers */
+ IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */
+ IPSTATS_MIB_OUTPKTS, /* OutRequests */
+ IPSTATS_MIB_OUTOCTETS, /* OutOctets */
+/* other fields */
IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */
IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */
IPSTATS_MIB_INNOROUTES, /* InNoRoutes */
@@ -26,9 +33,6 @@ enum
IPSTATS_MIB_INUNKNOWNPROTOS, /* InUnknownProtos */
IPSTATS_MIB_INTRUNCATEDPKTS, /* InTruncatedPkts */
IPSTATS_MIB_INDISCARDS, /* InDiscards */
- IPSTATS_MIB_INDELIVERS, /* InDelivers */
- IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */
- IPSTATS_MIB_OUTPKTS, /* OutRequests */
IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */
IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */
IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */
@@ -42,8 +46,6 @@ enum
IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */
IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */
IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */
- IPSTATS_MIB_INOCTETS, /* InOctets */
- IPSTATS_MIB_OUTOCTETS, /* OutOctets */
IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */
IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */
IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */
^ permalink raw reply related
* [PATCH] net: avoid reloads in SNMP_UPD_PO_STATS
From: Eric Dumazet @ 2012-08-05 6:26 UTC (permalink / raw)
To: David Miller; +Cc: netdev
From: Eric Dumazet <edumazet@google.com>
Avoid two instructions to reload dev->nd_net->mib.ip_statistics pointer,
unsing a temp variable, in ip_rcv(), ip_output() paths for example.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/snmp.h | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 0147b90..7159626 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -154,13 +154,15 @@ struct linux_xfrm_mib {
*/
#define SNMP_UPD_PO_STATS(mib, basefield, addend) \
do { \
- this_cpu_inc(mib[0]->mibs[basefield##PKTS]); \
- this_cpu_add(mib[0]->mibs[basefield##OCTETS], addend); \
+ __typeof__(*mib[0]->mibs) *ptr = mib[0]->mibs; \
+ this_cpu_inc(ptr[basefield##PKTS]); \
+ this_cpu_add(ptr[basefield##OCTETS], addend); \
} while (0)
#define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \
do { \
- __this_cpu_inc(mib[0]->mibs[basefield##PKTS]); \
- __this_cpu_add(mib[0]->mibs[basefield##OCTETS], addend); \
+ __typeof__(*mib[0]->mibs) *ptr = mib[0]->mibs; \
+ __this_cpu_inc(ptr[basefield##PKTS]); \
+ __this_cpu_add(ptr[basefield##OCTETS], addend); \
} while (0)
^ permalink raw reply related
* Re: Bridge extensions to iproute2
From: Stephen Hemminger @ 2012-08-05 2:45 UTC (permalink / raw)
To: Maciej Żenczykowski; +Cc: Stephen Hemminger, Linux NetDev, David Miller
There is barely any overlap between bridge-utils and iproute2.
I was thinking of making a script 'brctl' that does same thing as
old utility but using new netlink based commands.
^ permalink raw reply
* Re: Bridge extensions to iproute2
From: Maciej Żenczykowski @ 2012-08-05 1:49 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: Linux NetDev, David Miller
In-Reply-To: <20120801170713.289e078e@nehalam.linuxnetplumber.net>
Thanks. Would it make sense to merge bridge-utils / brctl into iproute2?
On Wed, Aug 1, 2012 at 5:07 PM, Stephen Hemminger <shemminger@vyatta.com> wrote:
> On Tue, 10 Jul 2012 15:01:26 -0700
> Maciej Żenczykowski <zenczykowski@gmail.com> wrote:
>
>> > I will get back to these. There wasn't a motivation to go fast because
>> > there wasn't a user of these. Now with fdb offload support they are needed.
>>
>> Do you have some semi-ready patches that could be used for test purposes?
>>
>> While it looks like the forwarding database capability is there in the kernel,
>> I can't currently find an interface to turn learning off.
>
> I cleaned it up an put in 3.5.0 just released version.
^ permalink raw reply
* [PATCH 02/13] SCTP: register protocol for namespace handling.
From: Jan Ariyasu @ 2012-08-05 1:26 UTC (permalink / raw)
To: Vlad Yasevich, David S. Miller, linux-sctp, netdev, linux-kernel
Cc: Jan Ariyasu
Add namespace-helper functions to access per-namespace parameters
and variables. Create per-namespace control socket for out-of-the-
blue packets, initialize per-namespace protocol parameters, and
register SCTP protocol for namespace handling.
Signed-off-by: Jan Ariyasu <jan.ariyasu@hp.com>
---
include/net/sctp/sctp.h | 31 ++++-
net/sctp/input.c | 4 +-
net/sctp/protocol.c | 292 +++++++++++++++++++++++++++++++++++------------
net/sctp/sm_statefuns.c | 10 +-
4 files changed, 256 insertions(+), 81 deletions(-)
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index ff49964..c2dfeea 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -70,6 +70,8 @@
#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/idr.h>
+#include <net/net_namespace.h>
+#include <net/netns/generic.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <net/ipv6.h>
@@ -107,6 +109,9 @@
#define SCTP_STATIC static
#endif
+/* For namespace identification */
+extern int sctp_net_id;
+
/*
* Function declarations.
*/
@@ -114,7 +119,6 @@
/*
* sctp/protocol.c
*/
-extern struct sock *sctp_get_ctl_sock(void);
extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
sctp_scope_t, gfp_t gfp,
int flags);
@@ -719,4 +723,29 @@ static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *
return t->dst;
}
+/* Namespace helper functions */
+static inline struct sctp_ns_globals *sctp_get_ns_globals(struct net *net)
+{
+ struct sctp_ns_globals *ns_globals =
+ (struct sctp_ns_globals *) net_generic(net, sctp_net_id);
+ return ns_globals;
+
+}
+
+/* Return the address of the control sock. */
+static inline struct sock **sctp_get_ctl_sock(struct net *net)
+{
+ struct sctp_ns_globals *ns_globals =
+ (struct sctp_ns_globals *) net_generic(net, sctp_net_id);
+ return &ns_globals->sctp_ctl_sock;
+}
+
+/* Return the address of the protocol globals. */
+static inline struct sctp_net_params *sctp_get_params(struct net *net)
+{
+ struct sctp_ns_globals *ns_globals =
+ (struct sctp_ns_globals *) net_generic(net, sctp_net_id);
+ return &ns_globals->protocol_params;
+}
+
#endif /* __net_sctp_h__ */
diff --git a/net/sctp/input.c b/net/sctp/input.c
index e64d521..fc94829 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -200,7 +200,7 @@ int sctp_rcv(struct sk_buff *skb)
sctp_endpoint_put(ep);
ep = NULL;
}
- sk = sctp_get_ctl_sock();
+ sk = *(sctp_get_ctl_sock(&init_net));
ep = sctp_sk(sk)->ep;
sctp_endpoint_hold(ep);
rcvr = &ep->base;
@@ -787,7 +787,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
goto hit;
}
- ep = sctp_sk((sctp_get_ctl_sock()))->ep;
+ ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
hit:
sctp_endpoint_hold(ep);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index cafdaac..5c1a18c 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -78,11 +78,11 @@ struct proc_dir_entry *proc_net_sctp;
struct idr sctp_assocs_id;
DEFINE_SPINLOCK(sctp_assocs_id_lock);
-/* This is the global socket data structure used for responding to
- * the Out-of-the-blue (OOTB) packets. A control sock will be created
- * for this socket at the initialization time.
+/*
+ * This id will allow us to access per-namespace globals in
+ * struct sctp_ns_globals, defined as net_generic in struct net.
*/
-static struct sock *sctp_ctl_sock;
+int sctp_net_id __read_mostly;
static struct sctp_pf *sctp_pf_inet6_specific;
static struct sctp_pf *sctp_pf_inet_specific;
@@ -96,32 +96,33 @@ long sysctl_sctp_mem[3];
int sysctl_sctp_rmem[3];
int sysctl_sctp_wmem[3];
-/* Return the address of the control sock. */
-struct sock *sctp_get_ctl_sock(void)
-{
- return sctp_ctl_sock;
-}
-
/* Set up the proc fs entry for the SCTP protocol. */
static __init int sctp_proc_init(void)
{
#ifdef CONFIG_PROC_FS
+ int status = 0;
if (!proc_net_sctp) {
proc_net_sctp = proc_mkdir("sctp", init_net.proc_net);
- if (!proc_net_sctp)
- goto out_nomem;
+ if (!proc_net_sctp) {
+ status = -ENOMEM;
+ goto out;
+ }
}
- if (sctp_snmp_proc_init())
+ status = sctp_snmp_proc_init();
+ if (status)
goto out_snmp_proc_init;
- if (sctp_eps_proc_init())
+ status = sctp_eps_proc_init();
+ if (status)
goto out_eps_proc_init;
- if (sctp_assocs_proc_init())
+ status = sctp_assocs_proc_init();
+ if (status)
goto out_assocs_proc_init;
- if (sctp_remaddr_proc_init())
+ status = sctp_remaddr_proc_init();
+ if (status)
goto out_remaddr_proc_init;
- return 0;
+ return status;
out_remaddr_proc_init:
sctp_assocs_proc_exit();
@@ -134,9 +135,8 @@ out_snmp_proc_init:
proc_net_sctp = NULL;
remove_proc_entry("sctp", init_net.proc_net);
}
-
-out_nomem:
- return -ENOMEM;
+out:
+ return status;
#else
return 0;
#endif /* CONFIG_PROC_FS */
@@ -817,22 +817,23 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
* Initialize the control inode/socket with a control endpoint data
* structure. This endpoint is reserved exclusively for the OOTB processing.
*/
-static int sctp_ctl_sock_init(void)
+static int sctp_ctl_sock_init(struct net *net)
{
int err;
sa_family_t family = PF_INET;
+ struct sock **ctl_sock = sctp_get_ctl_sock(net);
if (sctp_get_pf_specific(PF_INET6))
family = PF_INET6;
- err = inet_ctl_sock_create(&sctp_ctl_sock, family,
- SOCK_SEQPACKET, IPPROTO_SCTP, &init_net);
+ err = inet_ctl_sock_create(ctl_sock, family,
+ SOCK_SEQPACKET, IPPROTO_SCTP, net);
/* If IPv6 socket could not be created, try the IPv4 socket */
if (err < 0 && family == PF_INET6)
- err = inet_ctl_sock_create(&sctp_ctl_sock, AF_INET,
+ err = inet_ctl_sock_create(ctl_sock, AF_INET,
SOCK_SEQPACKET, IPPROTO_SCTP,
- &init_net);
+ net);
if (err < 0) {
pr_err("Failed to create the SCTP control socket\n");
@@ -841,6 +842,12 @@ static int sctp_ctl_sock_init(void)
return 0;
}
+static inline void sctp_ctl_sock_destroy(struct net *net)
+{
+ struct sock **sctp_ctl_sk = sctp_get_ctl_sock(net);
+ inet_ctl_sock_destroy(*sctp_ctl_sk);
+}
+
/* Register address family specific functions. */
int sctp_register_af(struct sctp_af *af)
{
@@ -1151,17 +1158,18 @@ static void sctp_v4_pf_exit(void)
static int sctp_v4_protosw_init(void)
{
- int rc;
-
+ int rc = 0;
rc = proto_register(&sctp_prot, 1);
- if (rc)
+ if (rc) {
+ pr_err("Failed to register SCTP protocol\n");
return rc;
+ }
/* Register SCTP(UDP and TCP style) with socket layer. */
inet_register_protosw(&sctp_seqpacket_protosw);
inet_register_protosw(&sctp_stream_protosw);
- return 0;
+ return rc;
}
static void sctp_v4_protosw_exit(void)
@@ -1219,8 +1227,8 @@ static void sctp_global_param_init(void)
* Path.Max.Retrans - 5 attempts (per destination address)
* Max.Init.Retransmits - 8 attempts
*/
- sctp_max_retrans_association = 10;
- sctp_max_retrans_path = 5;
+ sctp_max_retrans_association = 10;
+ sctp_max_retrans_path = 5;
sctp_max_retrans_init = 8;
/* Sendbuffer growth - do per-socket accounting */
@@ -1238,8 +1246,8 @@ static void sctp_global_param_init(void)
/* Implementation specific variables. */
/* Initialize default stream count setup information. */
- sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
- sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
+ sctp_max_instreams = SCTP_DEFAULT_INSTREAMS;
+ sctp_max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
/* Initialize maximum autoclose timeout. */
sctp_max_autoclose = INT_MAX / HZ;
@@ -1263,6 +1271,112 @@ static void sctp_global_param_init(void)
return;
}
+
+static int sctp_net_param_init(struct net *net)
+{
+ struct sctp_net_params *net_params = sctp_get_params(net);
+ struct sctp_ns_globals *ns_globals = sctp_get_ns_globals(net);
+ if ((net_params == NULL) || (ns_globals == NULL))
+ return -ENOMEM;
+
+ /* Initialize SCTP protocol parameters
+ * 14. Suggested SCTP Protocol Parameter Values
+ */
+ /* The following protocol parameters are RECOMMENDED: */
+ /* RTO.Initial - 3 seconds */
+ net_params->rto_initial = SCTP_RTO_INITIAL;
+ /* RTO.Min - 1 second */
+ net_params->rto_min = SCTP_RTO_MIN;
+ /* RTO.Max - 60 seconds */
+ net_params->rto_max = SCTP_RTO_MAX;
+ /* RTO.Alpha - 1/8 */
+ net_params->rto_alpha = SCTP_RTO_ALPHA;
+ /* RTO.Beta - 1/4 */
+ net_params->rto_beta = SCTP_RTO_BETA;
+
+ /* Max.Burst - 4 */
+ net_params->max_burst = SCTP_DEFAULT_MAX_BURST;
+
+ /* Whether Cookie Preservative is enabled(1) or not(0) */
+ net_params->cookie_preserve_enable = 1;
+
+ /* Valid.Cookie.Life - 60 seconds */
+ net_params->valid_cookie_life = SCTP_DEFAULT_COOKIE_LIFE;
+
+ /* delayed SACK timeout */
+ net_params->sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK;
+
+ /* HB.interval - 30 seconds */
+ net_params->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT;
+
+ /* Association.Max.Retrans - 10 attempts
+ * Path.Max.Retrans - 5 attempts (per destination address)
+ * Max.Init.Retransmits - 8 attempts
+ */
+ net_params->max_retrans_association = 10;
+ net_params->max_retrans_path = 5;
+ net_params->max_retrans_init = 8;
+
+ /* Sendbuffer growth - do per-socket accounting */
+ net_params->sndbuf_policy = 0;
+
+ /* Rcvbuffer growth - do per-socket accounting */
+ net_params->rcvbuf_policy = 0;
+
+ /* Implementation specific variables. */
+
+ /* Initialize default stream count setup information. */
+ net_params->max_instreams = SCTP_DEFAULT_INSTREAMS;
+ net_params->max_outstreams = SCTP_DEFAULT_OUTSTREAMS;
+
+ /* hash of all endpoints */
+ net_params->ep_hashsize = 64;
+ net_params->ep_hashtable = NULL;
+
+ /* hash of all associations */
+ net_params->assoc_hashsize = 0;
+ net_params->assoc_hashtable = NULL;
+
+ /* port-control hash */
+ net_params->port_hashsize = 0;
+ net_params->port_hashtable = NULL;
+
+ /* Initialize local address list */
+ INIT_LIST_HEAD(&net_params->local_addr_list);
+ spin_lock_init(&net_params->addr_list_lock);
+ idr_init(&ns_globals->assocs_id);
+ spin_lock_init(&ns_globals->assocs_id_lock);
+
+ /* Disable ADDIP by default. */
+ net_params->addip_enable = 0;
+ net_params->addip_noauth_enable = 0;
+ net_params->default_auto_asconf = 0;
+
+ /* Set SCOPE policy to enabled */
+ net_params->ipv4_scope_policy = SCTP_SCOPE_POLICY_ENABLE;
+
+ /* Set the default rwnd update threshold */
+ net_params->rwnd_update_shift = SCTP_DEFAULT_RWND_SHIFT;
+
+ /* Enable PR-SCTP by default. */
+ net_params->prsctp_enable = 1;
+
+ /* Disable AUTH by default. */
+ net_params->auth_enable = 0;
+
+ /* Initialize maximum autoclose timeout. */
+ net_params->max_autoclose = INT_MAX / HZ;
+
+ /* Initialize address event list */
+ INIT_LIST_HEAD(&net_params->addr_waitq);
+ net_params->addr_wq_timer.expires = 0;
+ INIT_LIST_HEAD(&net_params->auto_asconf_splist);
+ spin_lock_init(&net_params->addr_wq_lock);
+ setup_timer(&net_params->addr_wq_timer, sctp_addr_wq_timeout_handler,
+ (unsigned long)net);
+ return 0;
+}
+
static void sctp_memory_globals_init(void)
{
unsigned long limit;
@@ -1318,13 +1432,13 @@ static int sctp_hashtable_globals_init(void)
continue;
sctp_assoc_hashtable = (struct sctp_hashbucket *)
__get_free_pages(GFP_ATOMIC|__GFP_NOWARN|__GFP_ZERO,
- order);
+ order);
} while (!sctp_assoc_hashtable && (--order > 0));
if (!sctp_assoc_hashtable) {
pr_err("Failed association hash alloc\n");
status = -ENOMEM;
- goto err_ahash_alloc;
+ goto out;
}
for (i = 0; i < sctp_assoc_hashsize; i++) {
rwlock_init(&sctp_assoc_hashtable[i].lock);
@@ -1377,8 +1491,6 @@ err_ehash_alloc:
free_pages((unsigned long)sctp_assoc_hashtable,
get_order(sctp_assoc_hashsize *
sizeof(struct sctp_hashbucket)));
-err_ahash_alloc:
- sctp_proc_exit();
out:
return status;
}
@@ -1432,6 +1544,49 @@ static void sctp_kmem_cache_destroy(void)
kmem_cache_destroy(sctp_bucket_cachep);
}
+/* namespace enablers for init */
+
+static int __net_init sctp_net_init(struct net *net)
+{
+ int err = 0;
+
+ /* Set up the control socket for OOTB packets */
+ err = sctp_ctl_sock_init(net);
+ if (err)
+ goto out;
+
+ err = sctp_net_param_init(net);
+ if (err)
+ goto err_param_init;
+
+err_param_init:
+ sctp_ctl_sock_destroy(net);
+out:
+ return err;
+}
+
+static void __net_exit sctp_net_exit(struct net *net)
+{
+ sctp_ctl_sock_destroy(net);
+}
+
+static __net_initdata struct pernet_operations sctp_sk_ops = {
+ .init = sctp_net_init,
+ .exit = sctp_net_exit,
+ .id = &sctp_net_id,
+ .size = sizeof(struct sctp_ns_globals),
+};
+
+static int __net_init sctp_ns_init(void)
+{
+ return register_pernet_subsys(&sctp_sk_ops);
+}
+
+static void __net_exit sctp_ns_exit(void)
+{
+ unregister_pernet_subsys(&sctp_sk_ops);
+}
+
/* Initialize the universe into something sensible. */
SCTP_STATIC __init int sctp_init(void)
{
@@ -1452,26 +1607,11 @@ SCTP_STATIC __init int sctp_init(void)
goto err_percpu_counter_init;
}
- /* Allocate and initialise sctp mibs. */
- status = init_sctp_mibs();
- if (status)
- goto err_init_mibs;
-
- /* Initialize proc fs directory. */
- status = sctp_proc_init();
- if (status)
- goto err_init_proc;
-
- /* Initialize object count debugging. */
- sctp_dbg_objcnt_init();
-
/* Initialize global parameters */
sctp_global_param_init();
sctp_memory_globals_init();
sctp_hashtable_globals_init();
- sctp_sysctl_register();
-
/* Register the routines for different a-f handling */
INIT_LIST_HEAD(&sctp_address_families);
sctp_v4_pf_init();
@@ -1498,22 +1638,32 @@ SCTP_STATIC __init int sctp_init(void)
if (status)
goto err_v6_protosw_init;
- /* Initialize the control inode/socket for handling OOTB packets. */
- if ((status = sctp_ctl_sock_init())) {
- pr_err("Failed to initialize the SCTP control sock\n");
- goto err_ctl_sock_init;
- }
-
status = sctp_v4_add_protocol();
if (status)
goto err_add_protocol;
- /* Register SCTP with inet6 layer. */
status = sctp_v6_add_protocol();
if (status)
goto err_v6_add_protocol;
- /* Set up sysctl parameters. */
+ /*
+ * Register for pernet packet handling
+ */
+ status = sctp_ns_init();
+ if (status) {
+ pr_err("Failed to register SCTP for namespaces\n");
+ goto err_ns_init;
+ }
+
+ /* Initialize proc fs directory. */
+ status = sctp_proc_init();
+ if (status)
+ goto err_init_proc;
+
+ /* Initialize object count debugging. */
+ sctp_dbg_objcnt_init();
+
+ /* Set up sysctl parameters. */
sctp_sysctl_register();
/* Allocate and initialise sctp mibs. */
@@ -1526,26 +1676,23 @@ SCTP_STATIC __init int sctp_init(void)
err_mib_init:
sctp_sysctl_unregister();
+ sctp_dbg_objcnt_exit();
+ sctp_proc_exit();
+err_init_proc:
+ sctp_ns_exit();
+err_ns_init:
sctp_v6_del_protocol();
err_v6_add_protocol:
sctp_v4_del_protocol();
err_add_protocol:
- inet_ctl_sock_destroy(sctp_ctl_sock);
-err_ctl_sock_init:
sctp_v6_protosw_exit();
err_v6_protosw_init:
sctp_v4_protosw_exit();
err_protosw_init:
sctp_free_local_addr_list();
- sctp_v4_pf_exit();
sctp_v6_pf_exit();
- sctp_sysctl_unregister();
+ sctp_v4_pf_exit();
sctp_hashtable_globals_free();
- sctp_dbg_objcnt_exit();
- sctp_proc_exit();
-err_init_proc:
- cleanup_sctp_mibs();
-err_init_mibs:
percpu_counter_destroy(&sctp_sockets_allocated);
err_percpu_counter_init:
sctp_kmem_cache_destroy();
@@ -1565,9 +1712,6 @@ SCTP_STATIC __exit void sctp_exit(void)
sctp_v4_del_protocol();
sctp_free_addr_wq();
- /* Free the control endpoint. */
- inet_ctl_sock_destroy(sctp_ctl_sock);
-
/* Free protosw registrations */
sctp_v6_protosw_exit();
sctp_v4_protosw_exit();
@@ -1580,7 +1724,6 @@ SCTP_STATIC __exit void sctp_exit(void)
sctp_v4_pf_exit();
sctp_sysctl_unregister();
-
sctp_hashtable_globals_free();
sctp_dbg_objcnt_exit();
@@ -1588,6 +1731,9 @@ SCTP_STATIC __exit void sctp_exit(void)
percpu_counter_destroy(&sctp_sockets_allocated);
cleanup_sctp_mibs();
+ /* Unregister from namespaces */
+ sctp_ns_exit();
+
rcu_barrier(); /* Wait for completion of call_rcu()'s */
sctp_kmem_cache_destroy();
}
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 9fca103..91dcdd6 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -318,7 +318,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
/* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT.
*/
- if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) {
+ if (ep == sctp_sk((*(sctp_get_ctl_sock(&init_net))))->ep) {
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
}
@@ -650,7 +650,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
/* If the packet is an OOTB packet which is temporarily on the
* control endpoint, respond with an ABORT.
*/
- if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) {
+ if (ep == sctp_sk((*(sctp_get_ctl_sock(&init_net))))->ep) {
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
}
@@ -1197,7 +1197,7 @@ static int sctp_sf_send_restart_abort(union sctp_addr *ssa,
errhdr->length = htons(len);
/* Assign to the control socket. */
- ep = sctp_sk((sctp_get_ctl_sock()))->ep;
+ ep = sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep;
/* Association is NULL since this may be a restart attack and we
* want to send back the attacker's vtag.
@@ -1653,7 +1653,7 @@ sctp_disposition_t sctp_sf_do_5_2_3_initack(const struct sctp_endpoint *ep,
/* Per the above section, we'll discard the chunk if we have an
* endpoint. If this is an OOTB INIT-ACK, treat it as such.
*/
- if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
+ if (ep == sctp_sk(*(sctp_get_ctl_sock(&init_net)))->ep)
return sctp_sf_ootb(ep, asoc, type, arg, commands);
else
return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
@@ -5919,7 +5919,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(const struct sctp_association *asoc
* the source address.
*/
sctp_transport_route(transport, (union sctp_addr *)&chunk->dest,
- sctp_sk(sctp_get_ctl_sock()));
+ sctp_sk(*sctp_get_ctl_sock(&init_net)));
packet = sctp_packet_init(&transport->packet, transport, sport, dport);
packet = sctp_packet_config(packet, vtag, 0);
--
1.7.9.5
^ permalink raw reply related
* Re: [RFC v2 2/7] user_ns: use new hashtable implementation
From: Eric W. Biederman @ 2012-08-05 0:58 UTC (permalink / raw)
To: Sasha Levin
Cc: torvalds, tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
rostedt, mingo, aarcange, ericvh, netdev
In-Reply-To: <1344003788-1417-3-git-send-email-levinsasha928@gmail.com>
Sasha Levin <levinsasha928@gmail.com> writes:
> Switch user_ns to use the new hashtable implementation. This reduces the amount of
> generic unrelated code in user_ns.
Just looking at this ick.
- Your comparison function is broken.
- The naming is awkward.
hash_get without a reference count being incremented?
- The magic is deep.
hash_get is named like a function but takes a piece of code to call
like only a macro can.
- uid_hash_find always bumped the reference count
but your uidhash_entry doesn't nor do all of the callers of
uidhash_entry bump the reference count.
Nacked-by: "Eric W. Biederman" <ebiederm@xmission.com>
I don't have the time for a new improved better hash table that makes
the code buggier.
Eric
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> kernel/user.c | 53 ++++++++++++++++++-----------------------------------
> 1 files changed, 18 insertions(+), 35 deletions(-)
>
> diff --git a/kernel/user.c b/kernel/user.c
> index b815fef..555c71a 100644
> --- a/kernel/user.c
> +++ b/kernel/user.c
> @@ -16,6 +16,7 @@
> #include <linux/interrupt.h>
> #include <linux/export.h>
> #include <linux/user_namespace.h>
> +#include <linux/hashtable.h>
>
> /*
> * userns count is 1 for root user, 1 for init_uts_ns,
> @@ -50,15 +51,14 @@ EXPORT_SYMBOL_GPL(init_user_ns);
> * UID task count cache, to get fast user lookup in "alloc_uid"
> * when changing user ID's (ie setuid() and friends).
> */
> -
> -#define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 7)
> -#define UIDHASH_SZ (1 << UIDHASH_BITS)
> -#define UIDHASH_MASK (UIDHASH_SZ - 1)
> -#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK)
> -#define uidhashentry(uid) (uidhash_table + __uidhashfn((__kuid_val(uid))))
> +#define UIDHASH_BITS (CONFIG_BASE_SMALL ? 3 : 7)
> +#define UIDHASH_CMP(obj, key) ((obj)->uid == (key))
> +#define uidhash_entry(key) (hash_get(&uidhash_table, key, \
> + struct user_struct, uidhash_node, \
> + UIDHASH_CMP))
>
> static struct kmem_cache *uid_cachep;
> -struct hlist_head uidhash_table[UIDHASH_SZ];
> +DEFINE_STATIC_HASHTABLE(uidhash_table, UIDHASH_BITS);
>
> /*
> * The uidhash_lock is mostly taken from process context, but it is
> @@ -84,29 +84,14 @@ struct user_struct root_user = {
> /*
> * These routines must be called with the uidhash spinlock held!
> */
> -static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent)
> +static void uid_hash_insert(struct user_struct *up)
> {
> - hlist_add_head(&up->uidhash_node, hashent);
> + hash_add(&uidhash_table, &up->uidhash_node, up->uid);
> }
>
> static void uid_hash_remove(struct user_struct *up)
> {
> - hlist_del_init(&up->uidhash_node);
> -}
> -
> -static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent)
> -{
> - struct user_struct *user;
> - struct hlist_node *h;
> -
> - hlist_for_each_entry(user, h, hashent, uidhash_node) {
> - if (uid_eq(user->uid, uid)) {
> - atomic_inc(&user->__count);
> - return user;
> - }
> - }
> -
> - return NULL;
> + hash_del(&up->uidhash_node);
> }
>
> /* IRQs are disabled and uidhash_lock is held upon function entry.
> @@ -135,7 +120,9 @@ struct user_struct *find_user(kuid_t uid)
> unsigned long flags;
>
> spin_lock_irqsave(&uidhash_lock, flags);
> - ret = uid_hash_find(uid, uidhashentry(uid));
> + ret = uidhash_entry(uid);
> + if (ret)
> + atomic_inc(&ret->__count);
> spin_unlock_irqrestore(&uidhash_lock, flags);
> return ret;
> }
> @@ -156,11 +143,10 @@ void free_uid(struct user_struct *up)
>
> struct user_struct *alloc_uid(kuid_t uid)
> {
> - struct hlist_head *hashent = uidhashentry(uid);
> struct user_struct *up, *new;
>
> spin_lock_irq(&uidhash_lock);
> - up = uid_hash_find(uid, hashent);
> + up = uidhash_entry(uid);
> spin_unlock_irq(&uidhash_lock);
>
> if (!up) {
> @@ -176,13 +162,13 @@ struct user_struct *alloc_uid(kuid_t uid)
> * on adding the same user already..
> */
> spin_lock_irq(&uidhash_lock);
> - up = uid_hash_find(uid, hashent);
> + up = uidhash_entry(uid);
> if (up) {
> key_put(new->uid_keyring);
> key_put(new->session_keyring);
> kmem_cache_free(uid_cachep, new);
> } else {
> - uid_hash_insert(new, hashent);
> + uid_hash_insert(new);
> up = new;
> }
> spin_unlock_irq(&uidhash_lock);
> @@ -196,17 +182,14 @@ out_unlock:
>
> static int __init uid_cache_init(void)
> {
> - int n;
> -
> uid_cachep = kmem_cache_create("uid_cache", sizeof(struct user_struct),
> 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
>
> - for(n = 0; n < UIDHASH_SZ; ++n)
> - INIT_HLIST_HEAD(uidhash_table + n);
> + hash_init(&uidhash_table, UIDHASH_BITS);
>
> /* Insert the root user immediately (init already runs as root) */
> spin_lock_irq(&uidhash_lock);
> - uid_hash_insert(&root_user, uidhashentry(GLOBAL_ROOT_UID));
> + uid_hash_insert(&root_user);
> spin_unlock_irq(&uidhash_lock);
>
> return 0;
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
* Re: [RFC v2 6/7] tracepoint: use new hashtable implementation
From: Steven Rostedt @ 2012-08-05 0:36 UTC (permalink / raw)
To: Sasha Levin
Cc: torvalds, tj, akpm, linux-kernel, linux-mm, paul.gortmaker, davem,
mingo, ebiederm, aarcange, ericvh, netdev, Mathieu Desnoyers
In-Reply-To: <1344003788-1417-7-git-send-email-levinsasha928@gmail.com>
FYI, Mathieu is the author of this file.
-- Steve
On Fri, 2012-08-03 at 16:23 +0200, Sasha Levin wrote:
> Switch tracepoints to use the new hashtable implementation. This reduces the amount of
> generic unrelated code in the tracepoints.
>
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> ---
> kernel/tracepoint.c | 26 +++++++++-----------------
> 1 files changed, 9 insertions(+), 17 deletions(-)
>
> diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
> index d96ba22..b5a2650 100644
> --- a/kernel/tracepoint.c
> +++ b/kernel/tracepoint.c
> @@ -26,6 +26,7 @@
> #include <linux/slab.h>
> #include <linux/sched.h>
> #include <linux/static_key.h>
> +#include <linux/hashtable.h>
>
> extern struct tracepoint * const __start___tracepoints_ptrs[];
> extern struct tracepoint * const __stop___tracepoints_ptrs[];
> @@ -49,8 +50,7 @@ static LIST_HEAD(tracepoint_module_list);
> * Protected by tracepoints_mutex.
> */
> #define TRACEPOINT_HASH_BITS 6
> -#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
> -static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
> +DEFINE_STATIC_HASHTABLE(tracepoint_table, TRACEPOINT_HASH_BITS);
>
> /*
> * Note about RCU :
> @@ -191,16 +191,14 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry,
> */
> static struct tracepoint_entry *get_tracepoint(const char *name)
> {
> - struct hlist_head *head;
> struct hlist_node *node;
> struct tracepoint_entry *e;
> u32 hash = jhash(name, strlen(name), 0);
>
> - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
> - hlist_for_each_entry(e, node, head, hlist) {
> + hash_for_each_possible(&tracepoint_table, node, e, hlist, hash)
> if (!strcmp(name, e->name))
> return e;
> - }
> +
> return NULL;
> }
>
> @@ -210,19 +208,13 @@ static struct tracepoint_entry *get_tracepoint(const char *name)
> */
> static struct tracepoint_entry *add_tracepoint(const char *name)
> {
> - struct hlist_head *head;
> - struct hlist_node *node;
> struct tracepoint_entry *e;
> size_t name_len = strlen(name) + 1;
> u32 hash = jhash(name, name_len-1, 0);
>
> - head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
> - hlist_for_each_entry(e, node, head, hlist) {
> - if (!strcmp(name, e->name)) {
> - printk(KERN_NOTICE
> - "tracepoint %s busy\n", name);
> - return ERR_PTR(-EEXIST); /* Already there */
> - }
> + if (get_tracepoint(name)) {
> + printk(KERN_NOTICE "tracepoint %s busy\n", name);
> + return ERR_PTR(-EEXIST); /* Already there */
> }
> /*
> * Using kmalloc here to allocate a variable length element. Could
> @@ -234,7 +226,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
> memcpy(&e->name[0], name, name_len);
> e->funcs = NULL;
> e->refcount = 0;
> - hlist_add_head(&e->hlist, head);
> + hash_add(&tracepoint_table, &e->hlist, hash);
> return e;
> }
>
> @@ -244,7 +236,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
> */
> static inline void remove_tracepoint(struct tracepoint_entry *e)
> {
> - hlist_del(&e->hlist);
> + hash_del(&e->hlist);
> kfree(e);
> }
>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply
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