* Re: [PATCH net-next 2/3] net: dsa: mediatek: combine MediaTek tag with VLAN tag
From: Sean Wang @ 2017-12-12 8:40 UTC (permalink / raw)
To: Andrew Lunn
Cc: davem, f.fainelli, vivien.didelot, netdev, linux-kernel,
linux-mediatek
In-Reply-To: <20171212082837.GM28672@lunn.ch>
On Tue, 2017-12-12 at 09:28 +0100, Andrew Lunn wrote:
> On Tue, Dec 12, 2017 at 03:21:21PM +0800, Sean Wang wrote:
> > On Thu, 2017-12-07 at 16:30 +0100, Andrew Lunn wrote:
> > > > @@ -25,20 +28,37 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
> > > > {
> > > > struct dsa_port *dp = dsa_slave_to_port(dev);
> > > > u8 *mtk_tag;
> > > > + bool is_vlan_skb = true;
> > >
> > > ..
> > >
> > > > + /* Mark tag attribute on special tag insertion to notify hardware
> > > > + * whether that's a combined special tag with 802.1Q header.
> > > > + */
> > > > + mtk_tag[0] = is_vlan_skb ? MTK_HDR_XMIT_TAGGED_TPID_8100 :
> > > > + MTK_HDR_XMIT_UNTAGGED;
> > > > mtk_tag[1] = (1 << dp->index) & MTK_HDR_XMIT_DP_BIT_MASK;
> > > > - mtk_tag[2] = 0;
> > > > - mtk_tag[3] = 0;
> > > > +
> > > > + /* Tag control information is kept for 802.1Q */
> > > > + if (!is_vlan_skb) {
> > > > + mtk_tag[2] = 0;
> > > > + mtk_tag[3] = 0;
> > > > + }
> > > >
> > > > return skb;
> > > > }
> > >
> > > Hi Sean
> > >
> > > So you can mark a packet for egress. What about ingress? How do you
> > > know the VLAN/PORT combination for packets the CPU receives? I would
> > > of expected a similar change to mtk_tag_rcv().
> > >
> > > Andrew
> >
> > Hi, Andrew
> >
> > It's unnecessary for extra handling in mtk_tag_rcv() when VLAN tag is
> > present since it is able to put the VLAN tag after the special tag and
> > then follow the existing way to parse.
>
> Hi Sean
>
> O.K. Please mention this in the commit message. Since it was something
> i was expecting, it should be documented why it is not needed.
>
> Thanks
> Andrew
Sure. I will add this in the commit message.
Sean
>
^ permalink raw reply
* Re: linux-next: build failure after merge of the mac80211-next tree
From: Johannes Berg @ 2017-12-12 8:46 UTC (permalink / raw)
To: Stephen Rothwell, Kalle Valo, Wireless
Cc: Linux-Next Mailing List, Linux Kernel Mailing List, Felix Fietkau,
Lorenzo Bianconi, Toke Høiland-Jørgensen, David Miller,
Networking
In-Reply-To: <20171212125805.5f7813fd@canb.auug.org.au>
Hi Stephen,
Thanks!
Felix made me aware of this yesterday evening and said he's going to
work out the required changes to mt76.
Kalle and I will make sure to submit the trees to Dave one by one so he
doesn't have to deal with it :)
Unfortunately, this might take a few days to resolve.
> -void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
> +void mt76_wake_tx_queue(struct ieee80211_hw *hw)
> {
> + struct ieee80211_txq *txq;
> struct mt76_dev *dev = hw->priv;
> - struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
> - struct mt76_queue *hwq = mtxq->hwq;
> + struct mt76_txq *mtxq;
> + struct mt76_queue *hwq;
>
> + txq = ieee80211_next_txq(hw);
> + mtxq = (struct mt76_txq *) txq->drv_priv;
> + hwq = mtxq->hwq;
Looks pretty much right to me - perhaps for safety there should be a
NULL check on txq, but OTOH when you get here it should be non-NULL.
Sorry for the inconvenience, I hadn't realized mt76 went in now.
johannes
^ permalink raw reply
* [PATCH] hippi: Fix a Fix a possible sleep-in-atomic bug in rr_close
From: Jia-Ju Bai @ 2017-12-12 8:49 UTC (permalink / raw)
To: jes, jes; +Cc: netdev, linux-kernel, Jia-Ju Bai
The driver may sleep under a spinlock.
The function call path is:
rr_close (acquire the spinlock)
free_irq --> may sleep
To fix it, free_irq is moved to the place without holding the spinlock.
This bug is found by my static analysis tool(DSAC) and checked by my code review.
Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
---
drivers/net/hippi/rrunner.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c
index 8483f03..1ab97d9 100644
--- a/drivers/net/hippi/rrunner.c
+++ b/drivers/net/hippi/rrunner.c
@@ -1379,8 +1379,8 @@ static int rr_close(struct net_device *dev)
rrpriv->info_dma);
rrpriv->info = NULL;
- free_irq(pdev->irq, dev);
spin_unlock_irqrestore(&rrpriv->lock, flags);
+ free_irq(pdev->irq, dev);
return 0;
}
--
1.7.9.5
^ permalink raw reply related
* [BUG] sbni: a possible sleep-in-atomic bug in sbni_close
From: Jia-Ju Bai @ 2017-12-12 8:53 UTC (permalink / raw)
To: davem, keescook, dhowells, timofeev; +Cc: netdev, Linux Kernel Mailing List
According to drivers/net/wan/sbni.c, the driver may sleep under a spinlock.
The function call path is:
sbni_close (acquire the spinlock)
free_irq --> may sleep
I do not find a good way to fix it, so I only report.
This possible bug is found by my static analysis tool (DSAC) and checked
by my code review.
Thanks,
Jia-Ju Bai
^ permalink raw reply
* [PATCH] drivers/staging/irda: fix max dup length for kstrndup
From: Ma Shimiao @ 2017-12-12 8:54 UTC (permalink / raw)
To: samuel; +Cc: netdev, linux-kernel, Ma Shimiao
If source string longer than max, kstrndup will alloc max+1 space.
So, we should make sure the result will not over limit.
Signed-off-by: Ma Shimiao <mashimiao.fnst@cn.fujitsu.com>
---
drivers/staging/irda/net/irias_object.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/irda/net/irias_object.c b/drivers/staging/irda/net/irias_object.c
index 53b86d0e1630..b626f796a3ff 100644
--- a/drivers/staging/irda/net/irias_object.c
+++ b/drivers/staging/irda/net/irias_object.c
@@ -56,7 +56,7 @@ struct ias_object *irias_new_object( char *name, int id)
}
obj->magic = IAS_OBJECT_MAGIC;
- obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
+ obj->name = kstrndup(name, IAS_MAX_CLASSNAME - 1, GFP_ATOMIC);
if (!obj->name) {
net_warn_ratelimited("%s(), Unable to allocate name!\n",
__func__);
@@ -326,7 +326,7 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value,
}
attrib->magic = IAS_ATTRIB_MAGIC;
- attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
+ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME - 1, GFP_ATOMIC);
/* Insert value */
attrib->value = irias_new_integer_value(value);
@@ -370,7 +370,7 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets,
}
attrib->magic = IAS_ATTRIB_MAGIC;
- attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
+ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME - 1, GFP_ATOMIC);
attrib->value = irias_new_octseq_value( octets, len);
if (!attrib->name || !attrib->value) {
@@ -412,7 +412,7 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value,
}
attrib->magic = IAS_ATTRIB_MAGIC;
- attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME, GFP_ATOMIC);
+ attrib->name = kstrndup(name, IAS_MAX_ATTRIBNAME - 1, GFP_ATOMIC);
attrib->value = irias_new_string_value(value);
if (!attrib->name || !attrib->value) {
@@ -468,7 +468,7 @@ struct ias_value *irias_new_string_value(char *string)
value->type = IAS_STRING;
value->charset = CS_ASCII;
- value->t.string = kstrndup(string, IAS_MAX_STRING, GFP_ATOMIC);
+ value->t.string = kstrndup(string, IAS_MAX_STRING - 1, GFP_ATOMIC);
if (!value->t.string) {
net_warn_ratelimited("%s: Unable to kmalloc!\n", __func__);
kfree(value);
--
2.13.6
^ permalink raw reply related
* Re: linux-next: build failure after merge of the mac80211-next tree
From: Toke Høiland-Jørgensen @ 2017-12-12 8:59 UTC (permalink / raw)
To: Johannes Berg, Stephen Rothwell, Kalle Valo, Wireless
Cc: Linux-Next Mailing List, Linux Kernel Mailing List, Felix Fietkau,
Lorenzo Bianconi, David Miller, Networking
In-Reply-To: <1513068419.26976.86.camel-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org> writes:
> Hi Stephen,
>
> Thanks!
>
> Felix made me aware of this yesterday evening and said he's going to
> work out the required changes to mt76.
>
> Kalle and I will make sure to submit the trees to Dave one by one so he
> doesn't have to deal with it :)
>
> Unfortunately, this might take a few days to resolve.
>
>> -void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
>> +void mt76_wake_tx_queue(struct ieee80211_hw *hw)
>> {
>> + struct ieee80211_txq *txq;
>> struct mt76_dev *dev = hw->priv;
>> - struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
>> - struct mt76_queue *hwq = mtxq->hwq;
>> + struct mt76_txq *mtxq;
>> + struct mt76_queue *hwq;
>>
>> + txq = ieee80211_next_txq(hw);
>> + mtxq = (struct mt76_txq *) txq->drv_priv;
>> + hwq = mtxq->hwq;
>
> Looks pretty much right to me - perhaps for safety there should be a
> NULL check on txq, but OTOH when you get here it should be non-NULL.
Note that while this will fix compilation it probably won't work right.
next_txq() is not guaranteed to return the same txq as was previously
passed in the wake_tx_queue() argument, so if this is the only place the
driver calls next_txq(), things are likely going to break.
Rather, the driver should call next_txq() whenever it schedules queues
instead of doing its own internal scheduling.
> Sorry for the inconvenience, I hadn't realized mt76 went in now.
Yeah, hadn't expected these streams to cross either. If Felix is looking
into this that is great; let me know if you need me to do anything else
on the mac80211 side. :)
-Toke
^ permalink raw reply
* Re: [PATCH net-next v4 1/2] bpf/tracing: allow user space to query prog array on the same tp
From: Peter Zijlstra @ 2017-12-12 9:03 UTC (permalink / raw)
To: Yonghong Song; +Cc: ast, daniel, netdev, kernel-team
In-Reply-To: <20171211193903.2428317-2-yhs@fb.com>
On Mon, Dec 11, 2017 at 11:39:02AM -0800, Yonghong Song wrote:
> The usage:
> struct perf_event_query_bpf *query = malloc(...);
> query.ids_len = ids_len;
> err = ioctl(pmu_efd, PERF_EVENT_IOC_QUERY_BPF, &query);
You didn't spot the fixes to your changelog ;-) The above should read
something like:
struct perf_event_query_bpf *query =
malloc(sizeof(*query) + sizeof(u32) * ids_len);
query->ids_len = ids_len;
err = ioctl(pmu_efd, PERF_EVENT_IOC_QUERY_BPF, query);
^ permalink raw reply
* [BUG] wl3501: a possible sleep-in-atomic bug in wl3501_reset
From: Jia-Ju Bai @ 2017-12-12 9:04 UTC (permalink / raw)
To: kvalo, mhchen, acme, niemeyer; +Cc: linux-wireless, netdev, linux-kernel
According to drivers/net/wireless/wl3501_cs.c, the driver may sleep
under a spinlock.
The function call path is:
wl3501_reset (acquire the spinlock)
free_irq --> may sleep
I do not find a good way to fix it, so I only report.
This possible bug is found by my static analysis tool (DSAC) and checked
by my code review.
Thanks,
Jia-Ju Bai
^ permalink raw reply
* Re: [PATCH net-next v5 2/2] net: ethernet: socionext: add AVE ethernet driver
From: Philippe Ombredanne @ 2017-12-12 9:14 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Russell King - ARM Linux, Kunihiko Hayashi, Mark Rutland,
Andrew Lunn, Florian Fainelli,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
netdev-u79uwXL29TY76Z2rM5mHXA, Linux kernel mailing list,
Masahiro Yamada, Rob Herring, Jassi Brar, David S. Miller,
linux-arm-kernel
In-Reply-To: <CAA93ih0C-aMpFAhU+5x6P=QjiOVRPZ0UL1wyKh1oeXzC8UjPXQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Dear Masami-san,
On Tue, Dec 12, 2017 at 3:29 AM, Masami Hiramatsu
<masami.hiramatsu-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
[...]
> Then what I'm considering is copyright notice lines. Those are usually
> treat as the header lines, not single line. So
>
>> +// SDPX-License-Identifier: GPL-2.0
>> +// sni_ave.c - Socionext UniPhier AVE ethernet driver
>> +// Copyright 2014 Panasonic Corporation
>> +// Copyright 2015-2017 Socionext Inc.
>
> is acceptable? or should we keep C-style header lines for new drivers?
>
>> +// SDPX-License-Identifier: GPL-2.0
>> +/*
>> + * sni_ave.c - Socionext UniPhier AVE ethernet driver
>> + * Copyright 2014 Panasonic Corporation
>> + * Copyright 2015-2017 Socionext Inc.
>> + */
>
> I just concern that those lines are not "single". that's all. :)
My voice carries the weight of a down feather in this discussion and
to me the benefit of the first form is that you have removed two
lines. Both forms work fine.
--
Cordially
Philippe Ombredanne
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] vsock.7: document VSOCK socket address family
From: Stefan Hajnoczi @ 2017-12-12 9:23 UTC (permalink / raw)
To: Michael Kerrisk (man-pages)
Cc: linux-man-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
Jorgen Hansen, G. Branden Robinson, Dexuan Cui
In-Reply-To: <cce43383-f42d-3c46-a34a-26e1c6a82af9-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1187 bytes --]
On Mon, Dec 11, 2017 at 08:32:20PM +0100, Michael Kerrisk (man-pages) wrote:
> On 12/05/2017 11:56 AM, Stefan Hajnoczi wrote:
> > +Data is transferred using the usual
> > +.BR send (2)
> > +and
> > +.BR recv (2)
>
> Or equally, write(2) and read(2), right? By failing to mention those, the
> text subtly implies that send(2) and recv(2) are preferred, but I don't
> suppose that is true.
>
> > +family of socket system calls.
Yes, this file descriptor is a socket so write(2) and read(2) work.
I said "family of socket system calls" to avoid listing all the
variations of send(2), sendmsg(2), sendfile(2), sendmmsg(2), etc but I
guess that doesn't include the read(2)/write(2) family of syscalls
(readv(2)/writev(2)).
Will send a follow-up patch to clarify this.
> > +.B EOPNOTSUPP
> > +Operation not supported. This includes:
> > +the
> > +.B MSG_OOB
> > +flag that is not implemented for
> > +.BR sendmsg (2)
> > +and
> > +.B MSG_PEEK
> > +for
> > +.BR recvmsg (2).
>
> So these errors might also occur for send() and recv(), right?
Yes, I'll change this to "the send(2) family of syscalls" and "recv(2)
family of syscalls", respectively.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
^ permalink raw reply
* [PATCH net-next 0/8] sctp: Implement Stream Interleave: Interaction with Other SCTP Extensions
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
Stream Interleave would be implemented in two Parts:
1. The I-DATA Chunk Supporting User Message Interleaving
2. Interaction with Other SCTP Extensions
Overview in section 2.3 of RFC8260 for Part 2:
The usage of the I-DATA chunk might interfere with other SCTP
extensions. Future SCTP extensions MUST describe if and how they
interfere with the usage of I-DATA chunks. For the SCTP extensions
already defined when this document was published, the details are
given in the following subsections.
As the 2nd part of Stream Interleave Implementation, this patchset mostly
adds the support for SCTP Partial Reliability Extension with I-FORWARD-TSN
chunk. Then adjusts stream scheduler and stream reconfig to make them work
properly with I-DATA chunks.
In the last patch, all stream interleave codes will be enabled by adding
sysctl to allow users to use this feature.
Xin Long (8):
sctp: add basic structures and make chunk function for ifwdtsn
sctp: implement generate_ftsn for sctp_stream_interleave
sctp: implement validate_ftsn for sctp_stream_interleave
sctp: implement report_ftsn for sctp_stream_interleave
sctp: implement handle_ftsn for sctp_stream_interleave
sctp: add stream interleave support in stream scheduler
sctp: update mid instead of ssn when doing stream and asoc reset
sctp: support sysctl to allow users to use stream interleave
include/linux/sctp.h | 17 +++
include/net/sctp/sm.h | 3 +
include/net/sctp/stream_interleave.h | 7 ++
include/net/sctp/structs.h | 12 ++
net/sctp/outqueue.c | 12 +-
net/sctp/sm_make_chunk.c | 24 ++++
net/sctp/sm_sideeffect.c | 24 +---
net/sctp/sm_statefuns.c | 24 ++--
net/sctp/sm_statetable.c | 3 +-
net/sctp/stream.c | 46 +++++---
net/sctp/stream_interleave.c | 216 +++++++++++++++++++++++++++++++++++
net/sctp/stream_sched.c | 3 +-
net/sctp/sysctl.c | 7 ++
13 files changed, 334 insertions(+), 64 deletions(-)
--
2.1.0
^ permalink raw reply
* [PATCH] mac80211_hwsim: Fix a possible sleep-in-atomic bug in hwsim_get_radio_nl
From: Jia-Ju Bai @ 2017-12-12 9:26 UTC (permalink / raw)
To: johannes, kvalo, j, jlopex
Cc: linux-wireless, netdev, linux-kernel, Jia-Ju Bai
The driver may sleep under a spinlock.
The function call path is:
hwsim_get_radio_nl (acquire the spinlock)
nlmsg_new(GFP_KERNEL) --> may sleep
To fix it, GFP_KERNEL is replaced with GFP_ATOMIC.
This bug is found by my static analysis tool(DSAC) and checked by my code review.
Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
---
drivers/net/wireless/mac80211_hwsim.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 10b075a..f2ebf4a 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3215,7 +3215,7 @@ static int hwsim_get_radio_nl(struct sk_buff *msg, struct genl_info *info)
if (!net_eq(wiphy_net(data->hw->wiphy), genl_info_net(info)))
continue;
- skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
if (!skb) {
res = -ENOMEM;
goto out_err;
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next 1/8] sctp: add basic structures and make chunk function for ifwdtsn
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
sctp_ifwdtsn_skip, sctp_ifwdtsn_hdr and sctp_ifwdtsn_chunk are used to
define and parse I-FWD TSN chunk format, and sctp_make_ifwdtsn is a
function to build the chunk.
The I-FORWARD-TSN Chunk Format is defined in section 2.3.1 of RFC8260.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/linux/sctp.h | 17 +++++++++++++++++
include/net/sctp/sm.h | 3 +++
include/net/sctp/structs.h | 1 +
net/sctp/sm_make_chunk.c | 24 ++++++++++++++++++++++++
4 files changed, 45 insertions(+)
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 38e2cf6..b36c766 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -110,6 +110,7 @@ enum sctp_cid {
/* Use hex, as defined in ADDIP sec. 3.1 */
SCTP_CID_ASCONF = 0xC1,
+ SCTP_CID_I_FWD_TSN = 0xC2,
SCTP_CID_ASCONF_ACK = 0x80,
SCTP_CID_RECONF = 0x82,
}; /* enum */
@@ -616,6 +617,22 @@ struct sctp_fwdtsn_chunk {
struct sctp_fwdtsn_hdr fwdtsn_hdr;
};
+struct sctp_ifwdtsn_skip {
+ __be16 stream;
+ __u8 reserved;
+ __u8 flags;
+ __be32 mid;
+};
+
+struct sctp_ifwdtsn_hdr {
+ __be32 new_cum_tsn;
+ struct sctp_ifwdtsn_skip skip[0];
+};
+
+struct sctp_ifwdtsn_chunk {
+ struct sctp_chunkhdr chunk_hdr;
+ struct sctp_ifwdtsn_hdr fwdtsn_hdr;
+};
/* ADDIP
* Section 3.1.1 Address Configuration Change Chunk (ASCONF)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 0993b49..2883c43 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -199,6 +199,9 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
const struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_idata(const struct sctp_association *asoc,
__u8 flags, int paylen, gfp_t gfp);
+struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
+ __u32 new_cum_tsn, size_t nstreams,
+ struct sctp_ifwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_datafrag_empty(const struct sctp_association *asoc,
const struct sctp_sndrcvinfo *sinfo,
int len, __u8 flags, gfp_t gfp);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 8ef638d..a5c3cf4 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -599,6 +599,7 @@ struct sctp_chunk {
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
struct sctp_authhdr *auth_hdr;
struct sctp_idatahdr *idata_hdr;
+ struct sctp_ifwdtsn_hdr *ifwdtsn_hdr;
} subh;
__u8 *chunk_end;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 23a7313..b9b269c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3536,6 +3536,30 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
return retval;
}
+struct sctp_chunk *sctp_make_ifwdtsn(const struct sctp_association *asoc,
+ __u32 new_cum_tsn, size_t nstreams,
+ struct sctp_ifwdtsn_skip *skiplist)
+{
+ struct sctp_chunk *retval = NULL;
+ struct sctp_ifwdtsn_hdr ftsn_hdr;
+ size_t hint;
+
+ hint = (nstreams + 1) * sizeof(__u32);
+
+ retval = sctp_make_control(asoc, SCTP_CID_I_FWD_TSN, 0, hint,
+ GFP_ATOMIC);
+ if (!retval)
+ return NULL;
+
+ ftsn_hdr.new_cum_tsn = htonl(new_cum_tsn);
+ retval->subh.ifwdtsn_hdr =
+ sctp_addto_chunk(retval, sizeof(ftsn_hdr), &ftsn_hdr);
+
+ sctp_addto_chunk(retval, nstreams * sizeof(skiplist[0]), skiplist);
+
+ return retval;
+}
+
/* RE-CONFIG 3.1 (RE-CONFIG chunk)
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 2/8] sctp: implement generate_ftsn for sctp_stream_interleave
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
generate_ftsn is added as a member of sctp_stream_interleave, used to
create fwdtsn or ifwdtsn chunk according to abandoned chunks, called
in sctp_retransmit and sctp_outq_sack.
sctp_generate_iftsn works for ifwdtsn, and sctp_generate_fwdtsn is
still used for making fwdtsn.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/stream_interleave.h | 2 +
include/net/sctp/structs.h | 1 +
net/sctp/outqueue.c | 12 +++---
net/sctp/stream_interleave.c | 75 ++++++++++++++++++++++++++++++++++++
4 files changed, 84 insertions(+), 6 deletions(-)
diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h
index 501b2be..66267db 100644
--- a/include/net/sctp/stream_interleave.h
+++ b/include/net/sctp/stream_interleave.h
@@ -47,6 +47,8 @@ struct sctp_stream_interleave {
struct sctp_chunk *chunk, gfp_t gfp);
void (*start_pd)(struct sctp_ulpq *ulpq, gfp_t gfp);
void (*abort_pd)(struct sctp_ulpq *ulpq, gfp_t gfp);
+ /* (I-)FORWARD-TSN process */
+ void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn);
};
void sctp_stream_interleave_init(struct sctp_stream *stream);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index a5c3cf4..b7720d6 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1100,6 +1100,7 @@ void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
void sctp_outq_uncork(struct sctp_outq *, gfp_t gfp);
void sctp_prsctp_prune(struct sctp_association *asoc,
struct sctp_sndrcvinfo *sinfo, int msg_len);
+void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
/* Uncork and flush an outqueue. */
static inline void sctp_outq_cork(struct sctp_outq *q)
{
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 7d67fee..af9b5eb 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -67,8 +67,6 @@ static void sctp_mark_missing(struct sctp_outq *q,
__u32 highest_new_tsn,
int count_of_newacks);
-static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 sack_ctsn);
-
static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp);
/* Add data to the front of the queue. */
@@ -591,7 +589,7 @@ void sctp_retransmit(struct sctp_outq *q, struct sctp_transport *transport,
* following the procedures outlined in C1 - C5.
*/
if (reason == SCTP_RTXR_T3_RTX)
- sctp_generate_fwdtsn(q, q->asoc->ctsn_ack_point);
+ q->asoc->stream.si->generate_ftsn(q, q->asoc->ctsn_ack_point);
/* Flush the queues only on timeout, since fast_rtx is only
* triggered during sack processing and the queue
@@ -942,6 +940,7 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
case SCTP_CID_ECN_ECNE:
case SCTP_CID_ASCONF:
case SCTP_CID_FWD_TSN:
+ case SCTP_CID_I_FWD_TSN:
case SCTP_CID_RECONF:
status = sctp_packet_transmit_chunk(packet, chunk,
one_packet, gfp);
@@ -956,7 +955,8 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
* sender MUST assure that at least one T3-rtx
* timer is running.
*/
- if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) {
+ if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN ||
+ chunk->chunk_hdr->type == SCTP_CID_I_FWD_TSN) {
sctp_transport_reset_t3_rtx(transport);
transport->last_time_sent = jiffies;
}
@@ -1372,7 +1372,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_chunk *chunk)
asoc->peer.rwnd = sack_a_rwnd;
- sctp_generate_fwdtsn(q, sack_ctsn);
+ asoc->stream.si->generate_ftsn(q, sack_ctsn);
pr_debug("%s: sack cumulative tsn ack:0x%x\n", __func__, sack_ctsn);
pr_debug("%s: cumulative tsn ack of assoc:%p is 0x%x, "
@@ -1795,7 +1795,7 @@ static inline int sctp_get_skip_pos(struct sctp_fwdtsn_skip *skiplist,
}
/* Create and add a fwdtsn chunk to the outq's control queue if needed. */
-static void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
+void sctp_generate_fwdtsn(struct sctp_outq *q, __u32 ctsn)
{
struct sctp_association *asoc = q->asoc;
struct sctp_chunk *ftsn_chunk = NULL;
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index 87b9417..2ead372 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -1082,6 +1082,77 @@ static void sctp_intl_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp)
sctp_ulpq_flush(ulpq);
}
+static inline int sctp_get_skip_pos(struct sctp_ifwdtsn_skip *skiplist,
+ int nskips, __be16 stream, __u8 flags)
+{
+ int i;
+
+ for (i = 0; i < nskips; i++)
+ if (skiplist[i].stream == stream &&
+ skiplist[i].flags == flags)
+ return i;
+
+ return i;
+}
+
+#define SCTP_FTSN_U_BIT 0x1
+static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn)
+{
+ struct sctp_ifwdtsn_skip ftsn_skip_arr[10];
+ struct sctp_association *asoc = q->asoc;
+ struct sctp_chunk *ftsn_chunk = NULL;
+ struct list_head *lchunk, *temp;
+ int nskips = 0, skip_pos;
+ struct sctp_chunk *chunk;
+ __u32 tsn;
+
+ if (!asoc->peer.prsctp_capable)
+ return;
+
+ if (TSN_lt(asoc->adv_peer_ack_point, ctsn))
+ asoc->adv_peer_ack_point = ctsn;
+
+ list_for_each_safe(lchunk, temp, &q->abandoned) {
+ chunk = list_entry(lchunk, struct sctp_chunk, transmitted_list);
+ tsn = ntohl(chunk->subh.data_hdr->tsn);
+
+ if (TSN_lte(tsn, ctsn)) {
+ list_del_init(lchunk);
+ sctp_chunk_free(chunk);
+ } else if (TSN_lte(tsn, asoc->adv_peer_ack_point + 1)) {
+ __be16 sid = chunk->subh.idata_hdr->stream;
+ __be32 mid = chunk->subh.idata_hdr->mid;
+ __u8 flags = 0;
+
+ if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
+ flags |= SCTP_FTSN_U_BIT;
+
+ asoc->adv_peer_ack_point = tsn;
+ skip_pos = sctp_get_skip_pos(&ftsn_skip_arr[0], nskips,
+ sid, flags);
+ ftsn_skip_arr[skip_pos].stream = sid;
+ ftsn_skip_arr[skip_pos].reserved = 0;
+ ftsn_skip_arr[skip_pos].flags = flags;
+ ftsn_skip_arr[skip_pos].mid = mid;
+ if (skip_pos == nskips)
+ nskips++;
+ if (nskips == 10)
+ break;
+ } else {
+ break;
+ }
+ }
+
+ if (asoc->adv_peer_ack_point > ctsn)
+ ftsn_chunk = sctp_make_ifwdtsn(asoc, asoc->adv_peer_ack_point,
+ nskips, &ftsn_skip_arr[0]);
+
+ if (ftsn_chunk) {
+ list_add_tail(&ftsn_chunk->list, &q->control_chunk_list);
+ SCTP_INC_STATS(sock_net(asoc->base.sk), SCTP_MIB_OUTCTRLCHUNKS);
+ }
+}
+
static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.data_chunk_len = sizeof(struct sctp_data_chunk),
/* DATA process functions */
@@ -1093,6 +1164,8 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.renege_events = sctp_ulpq_renege,
.start_pd = sctp_ulpq_partial_delivery,
.abort_pd = sctp_ulpq_abort_pd,
+ /* FORWARD-TSN process functions */
+ .generate_ftsn = sctp_generate_fwdtsn,
};
static struct sctp_stream_interleave sctp_stream_interleave_1 = {
@@ -1106,6 +1179,8 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.renege_events = sctp_renege_events,
.start_pd = sctp_intl_start_pd,
.abort_pd = sctp_intl_abort_pd,
+ /* I-FORWARD-TSN process functions */
+ .generate_ftsn = sctp_generate_iftsn,
};
void sctp_stream_interleave_init(struct sctp_stream *stream)
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 3/8] sctp: implement validate_ftsn for sctp_stream_interleave
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
validate_ftsn is added as a member of sctp_stream_interleave, used to
validate ssn/chunk type for fwdtsn or mid (message id)/chunk type for
ifwdtsn, called in sctp_sf_eat_fwd_tsn, just as validate_data.
If this check fails, an abort packet will be sent, as said in section
2.3.1 of RFC8260.
As ifwdtsn and fwdtsn chunks have different length, it also defines
ftsn_chunk_len for sctp_stream_interleave to describe the chunk size.
Then it replaces all sizeof(struct sctp_fwdtsn_chunk) with
sctp_ftsnchk_len.
It also adds the process for ifwdtsn in rx path. As Marcelo pointed
out, there's no need to add event table for ifwdtsn, but just share
prsctp_chunk_event_table with fwdtsn's. It would drop fwdtsn chunk
for ifwdtsn and drop ifwdtsn chunk for fwdtsn by calling validate_ftsn
in sctp_sf_eat_fwd_tsn.
After this patch, the ifwdtsn can be accepted.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/stream_interleave.h | 2 ++
include/net/sctp/structs.h | 10 ++++++++
net/sctp/sm_statefuns.c | 24 +++++++-------------
net/sctp/sm_statetable.c | 3 ++-
net/sctp/stream_interleave.c | 44 ++++++++++++++++++++++++++++++++++++
5 files changed, 66 insertions(+), 17 deletions(-)
diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h
index 66267db..0db15b5 100644
--- a/include/net/sctp/stream_interleave.h
+++ b/include/net/sctp/stream_interleave.h
@@ -33,6 +33,7 @@
struct sctp_stream_interleave {
__u16 data_chunk_len;
+ __u16 ftsn_chunk_len;
/* (I-)DATA process */
struct sctp_chunk *(*make_datafrag)(const struct sctp_association *asoc,
const struct sctp_sndrcvinfo *sinfo,
@@ -49,6 +50,7 @@ struct sctp_stream_interleave {
void (*abort_pd)(struct sctp_ulpq *ulpq, gfp_t gfp);
/* (I-)FORWARD-TSN process */
void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn);
+ bool (*validate_ftsn)(struct sctp_chunk *chunk);
};
void sctp_stream_interleave_init(struct sctp_stream *stream);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index b7720d6..8ac4d5c 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1443,6 +1443,16 @@ static inline __u16 sctp_datahdr_len(const struct sctp_stream *stream)
return stream->si->data_chunk_len - sizeof(struct sctp_chunkhdr);
}
+static inline __u16 sctp_ftsnchk_len(const struct sctp_stream *stream)
+{
+ return stream->si->ftsn_chunk_len;
+}
+
+static inline __u16 sctp_ftsnhdr_len(const struct sctp_stream *stream)
+{
+ return stream->si->ftsn_chunk_len - sizeof(struct sctp_chunkhdr);
+}
+
/* SCTP_GET_ASSOC_STATS counters */
struct sctp_priv_assoc_stats {
/* Maximum observed rto in the association during subsequent
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index c609c54..541f347 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -3957,7 +3957,6 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
{
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
struct sctp_chunk *chunk = arg;
- struct sctp_fwdtsn_skip *skip;
__u16 len;
__u32 tsn;
@@ -3971,7 +3970,7 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
/* Make sure that the FORWARD_TSN chunk has valid length. */
- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+ if (!sctp_chunk_length_valid(chunk, sctp_ftsnchk_len(&asoc->stream)))
return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
@@ -3990,14 +3989,11 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn(struct net *net,
if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
goto discard_noforce;
- /* Silently discard the chunk if stream-id is not valid */
- sctp_walk_fwdtsn(skip, chunk) {
- if (ntohs(skip->stream) >= asoc->stream.incnt)
- goto discard_noforce;
- }
+ if (!asoc->stream.si->validate_ftsn(chunk))
+ goto discard_noforce;
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
- if (len > sizeof(struct sctp_fwdtsn_hdr))
+ if (len > sctp_ftsnhdr_len(&asoc->stream))
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
SCTP_CHUNK(chunk));
@@ -4028,7 +4024,6 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
{
struct sctp_fwdtsn_hdr *fwdtsn_hdr;
struct sctp_chunk *chunk = arg;
- struct sctp_fwdtsn_skip *skip;
__u16 len;
__u32 tsn;
@@ -4042,7 +4037,7 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
return sctp_sf_unk_chunk(net, ep, asoc, type, arg, commands);
/* Make sure that the FORWARD_TSN chunk has a valid length. */
- if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_fwdtsn_chunk)))
+ if (!sctp_chunk_length_valid(chunk, sctp_ftsnchk_len(&asoc->stream)))
return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
commands);
@@ -4061,14 +4056,11 @@ enum sctp_disposition sctp_sf_eat_fwd_tsn_fast(
if (sctp_tsnmap_check(&asoc->peer.tsn_map, tsn) < 0)
goto gen_shutdown;
- /* Silently discard the chunk if stream-id is not valid */
- sctp_walk_fwdtsn(skip, chunk) {
- if (ntohs(skip->stream) >= asoc->stream.incnt)
- goto gen_shutdown;
- }
+ if (!asoc->stream.si->validate_ftsn(chunk))
+ goto gen_shutdown;
sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_FWDTSN, SCTP_U32(tsn));
- if (len > sizeof(struct sctp_fwdtsn_hdr))
+ if (len > sctp_ftsnhdr_len(&asoc->stream))
sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_FWDTSN,
SCTP_CHUNK(chunk));
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 8c9bb41..03a5d7e 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -992,7 +992,8 @@ static const struct sctp_sm_table_entry *sctp_chunk_event_lookup(
return &chunk_event_table[cid][state];
if (net->sctp.prsctp_enable) {
- if (cid == SCTP_CID_FWD_TSN)
+ if (cid == SCTP_CID_FWD_TSN ||
+ (net->sctp.intl_enable && cid == SCTP_CID_I_FWD_TSN))
return &prsctp_chunk_event_table[0][state];
}
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index 2ead372..cc4a5e3 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -1153,8 +1153,49 @@ static void sctp_generate_iftsn(struct sctp_outq *q, __u32 ctsn)
}
}
+#define _sctp_walk_ifwdtsn(pos, chunk, end) \
+ for (pos = chunk->subh.ifwdtsn_hdr->skip; \
+ (void *)pos < (void *)chunk->subh.ifwdtsn_hdr->skip + (end); pos++)
+
+#define sctp_walk_ifwdtsn(pos, ch) \
+ _sctp_walk_ifwdtsn((pos), (ch), ntohs((ch)->chunk_hdr->length) - \
+ sizeof(struct sctp_ifwdtsn_chunk))
+
+static bool sctp_validate_fwdtsn(struct sctp_chunk *chunk)
+{
+ struct sctp_fwdtsn_skip *skip;
+ __u16 incnt;
+
+ if (chunk->chunk_hdr->type != SCTP_CID_FWD_TSN)
+ return false;
+
+ incnt = chunk->asoc->stream.incnt;
+ sctp_walk_fwdtsn(skip, chunk)
+ if (ntohs(skip->stream) >= incnt)
+ return false;
+
+ return true;
+}
+
+static bool sctp_validate_iftsn(struct sctp_chunk *chunk)
+{
+ struct sctp_ifwdtsn_skip *skip;
+ __u16 incnt;
+
+ if (chunk->chunk_hdr->type != SCTP_CID_I_FWD_TSN)
+ return false;
+
+ incnt = chunk->asoc->stream.incnt;
+ sctp_walk_ifwdtsn(skip, chunk)
+ if (ntohs(skip->stream) >= incnt)
+ return false;
+
+ return true;
+}
+
static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.data_chunk_len = sizeof(struct sctp_data_chunk),
+ .ftsn_chunk_len = sizeof(struct sctp_fwdtsn_chunk),
/* DATA process functions */
.make_datafrag = sctp_make_datafrag_empty,
.assign_number = sctp_chunk_assign_ssn,
@@ -1166,10 +1207,12 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.abort_pd = sctp_ulpq_abort_pd,
/* FORWARD-TSN process functions */
.generate_ftsn = sctp_generate_fwdtsn,
+ .validate_ftsn = sctp_validate_fwdtsn,
};
static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.data_chunk_len = sizeof(struct sctp_idata_chunk),
+ .ftsn_chunk_len = sizeof(struct sctp_ifwdtsn_chunk),
/* I-DATA process functions */
.make_datafrag = sctp_make_idatafrag_empty,
.assign_number = sctp_chunk_assign_mid,
@@ -1181,6 +1224,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.abort_pd = sctp_intl_abort_pd,
/* I-FORWARD-TSN process functions */
.generate_ftsn = sctp_generate_iftsn,
+ .validate_ftsn = sctp_validate_iftsn,
};
void sctp_stream_interleave_init(struct sctp_stream *stream)
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 4/8] sctp: implement report_ftsn for sctp_stream_interleave
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
report_ftsn is added as a member of sctp_stream_interleave, used to
skip tsn from tsnmap, remove old events from reasm or lobby queue,
and abort pd for data or idata, called for SCTP_CMD_REPORT_FWDTSN
cmd and asoc reset.
sctp_report_iftsn works for ifwdtsn, and sctp_report_fwdtsn works
for fwdtsn. Note that sctp_report_iftsn doesn't do asoc abort_pd,
as stream abort_pd will be done when handling ifwdtsn. But when
ftsn is equal with ftsn, which means asoc reset, asoc abot_pd has
to be done.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/stream_interleave.h | 1 +
net/sctp/sm_sideeffect.c | 9 +------
net/sctp/stream.c | 6 ++---
net/sctp/stream_interleave.c | 48 ++++++++++++++++++++++++++++++++++++
4 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h
index 0db15b5..0b55c70 100644
--- a/include/net/sctp/stream_interleave.h
+++ b/include/net/sctp/stream_interleave.h
@@ -51,6 +51,7 @@ struct sctp_stream_interleave {
/* (I-)FORWARD-TSN process */
void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn);
bool (*validate_ftsn)(struct sctp_chunk *chunk);
+ void (*report_ftsn)(struct sctp_ulpq *ulpq, __u32 ftsn);
};
void sctp_stream_interleave_init(struct sctp_stream *stream);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 8adde71..be7c6dbd 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1368,14 +1368,7 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
break;
case SCTP_CMD_REPORT_FWDTSN:
- /* Move the Cumulattive TSN Ack ahead. */
- sctp_tsnmap_skip(&asoc->peer.tsn_map, cmd->obj.u32);
-
- /* purge the fragmentation queue */
- sctp_ulpq_reasm_flushtsn(&asoc->ulpq, cmd->obj.u32);
-
- /* Abort any in progress partial delivery. */
- sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
+ asoc->stream.si->report_ftsn(&asoc->ulpq, cmd->obj.u32);
break;
case SCTP_CMD_PROCESS_FWDTSN:
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index 8370e6c..b3a9f37 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -754,8 +754,7 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
* performed.
*/
max_tsn_seen = sctp_tsnmap_get_max_tsn_seen(&asoc->peer.tsn_map);
- sctp_ulpq_reasm_flushtsn(&asoc->ulpq, max_tsn_seen);
- sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
+ asoc->stream.si->report_ftsn(&asoc->ulpq, max_tsn_seen);
/* G1: Compute an appropriate value for the Receiver's Next TSN -- the
* TSN that the peer should use to send the next DATA chunk. The
@@ -1024,8 +1023,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
&asoc->peer.tsn_map);
LIST_HEAD(temp);
- sctp_ulpq_reasm_flushtsn(&asoc->ulpq, mtsn);
- sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC);
+ asoc->stream.si->report_ftsn(&asoc->ulpq, mtsn);
sctp_tsnmap_init(&asoc->peer.tsn_map,
SCTP_TSN_MAP_INITIAL,
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index cc4a5e3..f62771cc 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -1193,6 +1193,52 @@ static bool sctp_validate_iftsn(struct sctp_chunk *chunk)
return true;
}
+static void sctp_report_fwdtsn(struct sctp_ulpq *ulpq, __u32 ftsn)
+{
+ /* Move the Cumulattive TSN Ack ahead. */
+ sctp_tsnmap_skip(&ulpq->asoc->peer.tsn_map, ftsn);
+ /* purge the fragmentation queue */
+ sctp_ulpq_reasm_flushtsn(ulpq, ftsn);
+ /* Abort any in progress partial delivery. */
+ sctp_ulpq_abort_pd(ulpq, GFP_ATOMIC);
+}
+
+static void sctp_intl_reasm_flushtsn(struct sctp_ulpq *ulpq, __u32 ftsn)
+{
+ struct sk_buff *pos, *tmp;
+
+ skb_queue_walk_safe(&ulpq->reasm, pos, tmp) {
+ struct sctp_ulpevent *event = sctp_skb2event(pos);
+ __u32 tsn = event->tsn;
+
+ if (TSN_lte(tsn, ftsn)) {
+ __skb_unlink(pos, &ulpq->reasm);
+ sctp_ulpevent_free(event);
+ }
+ }
+
+ skb_queue_walk_safe(&ulpq->reasm_uo, pos, tmp) {
+ struct sctp_ulpevent *event = sctp_skb2event(pos);
+ __u32 tsn = event->tsn;
+
+ if (TSN_lte(tsn, ftsn)) {
+ __skb_unlink(pos, &ulpq->reasm_uo);
+ sctp_ulpevent_free(event);
+ }
+ }
+}
+
+static void sctp_report_iftsn(struct sctp_ulpq *ulpq, __u32 ftsn)
+{
+ /* Move the Cumulattive TSN Ack ahead. */
+ sctp_tsnmap_skip(&ulpq->asoc->peer.tsn_map, ftsn);
+ /* purge the fragmentation queue */
+ sctp_intl_reasm_flushtsn(ulpq, ftsn);
+ /* abort only when it's for all data */
+ if (ftsn == sctp_tsnmap_get_max_tsn_seen(&ulpq->asoc->peer.tsn_map))
+ sctp_intl_abort_pd(ulpq, GFP_ATOMIC);
+}
+
static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.data_chunk_len = sizeof(struct sctp_data_chunk),
.ftsn_chunk_len = sizeof(struct sctp_fwdtsn_chunk),
@@ -1208,6 +1254,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = {
/* FORWARD-TSN process functions */
.generate_ftsn = sctp_generate_fwdtsn,
.validate_ftsn = sctp_validate_fwdtsn,
+ .report_ftsn = sctp_report_fwdtsn,
};
static struct sctp_stream_interleave sctp_stream_interleave_1 = {
@@ -1225,6 +1272,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = {
/* I-FORWARD-TSN process functions */
.generate_ftsn = sctp_generate_iftsn,
.validate_ftsn = sctp_validate_iftsn,
+ .report_ftsn = sctp_report_iftsn,
};
void sctp_stream_interleave_init(struct sctp_stream *stream)
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 5/8] sctp: implement handle_ftsn for sctp_stream_interleave
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
handle_ftsn is added as a member of sctp_stream_interleave, used to skip
ssn for data or mid for idata, called for SCTP_CMD_PROCESS_FWDTSN cmd.
sctp_handle_iftsn works for ifwdtsn, and sctp_handle_fwdtsn works for
fwdtsn. Note that different from sctp_handle_fwdtsn, sctp_handle_iftsn
could do stream abort pd.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/net/sctp/stream_interleave.h | 2 ++
net/sctp/sm_sideeffect.c | 15 ++---------
net/sctp/stream_interleave.c | 49 ++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h
index 0b55c70..6657711 100644
--- a/include/net/sctp/stream_interleave.h
+++ b/include/net/sctp/stream_interleave.h
@@ -52,6 +52,8 @@ struct sctp_stream_interleave {
void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn);
bool (*validate_ftsn)(struct sctp_chunk *chunk);
void (*report_ftsn)(struct sctp_ulpq *ulpq, __u32 ftsn);
+ void (*handle_ftsn)(struct sctp_ulpq *ulpq,
+ struct sctp_chunk *chunk);
};
void sctp_stream_interleave_init(struct sctp_stream *stream);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index be7c6dbd..16ddf2c 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1007,18 +1007,6 @@ static void sctp_cmd_process_operr(struct sctp_cmd_seq *cmds,
}
}
-/* Process variable FWDTSN chunk information. */
-static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq,
- struct sctp_chunk *chunk)
-{
- struct sctp_fwdtsn_skip *skip;
-
- /* Walk through all the skipped SSNs */
- sctp_walk_fwdtsn(skip, chunk) {
- sctp_ulpq_skip(ulpq, ntohs(skip->stream), ntohs(skip->ssn));
- }
-}
-
/* Helper function to remove the association non-primary peer
* transports.
*/
@@ -1372,7 +1360,8 @@ static int sctp_cmd_interpreter(enum sctp_event event_type,
break;
case SCTP_CMD_PROCESS_FWDTSN:
- sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.chunk);
+ asoc->stream.si->handle_ftsn(&asoc->ulpq,
+ cmd->obj.chunk);
break;
case SCTP_CMD_GEN_SACK:
diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c
index f62771cc..8c7cf8f 100644
--- a/net/sctp/stream_interleave.c
+++ b/net/sctp/stream_interleave.c
@@ -1239,6 +1239,53 @@ static void sctp_report_iftsn(struct sctp_ulpq *ulpq, __u32 ftsn)
sctp_intl_abort_pd(ulpq, GFP_ATOMIC);
}
+static void sctp_handle_fwdtsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk)
+{
+ struct sctp_fwdtsn_skip *skip;
+
+ /* Walk through all the skipped SSNs */
+ sctp_walk_fwdtsn(skip, chunk)
+ sctp_ulpq_skip(ulpq, ntohs(skip->stream), ntohs(skip->ssn));
+}
+
+static void sctp_intl_skip(struct sctp_ulpq *ulpq, __u16 sid, __u32 mid,
+ __u8 flags)
+{
+ struct sctp_stream_in *sin = sctp_stream_in(ulpq->asoc, sid);
+ struct sctp_stream *stream = &ulpq->asoc->stream;
+
+ if (flags & SCTP_FTSN_U_BIT) {
+ if (sin->pd_mode_uo && MID_lt(sin->mid_uo, mid)) {
+ sin->pd_mode_uo = 0;
+ sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x1,
+ GFP_ATOMIC);
+ }
+ return;
+ }
+
+ if (MID_lt(mid, sctp_mid_peek(stream, in, sid)))
+ return;
+
+ if (sin->pd_mode) {
+ sin->pd_mode = 0;
+ sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x0, GFP_ATOMIC);
+ }
+
+ sctp_mid_skip(stream, in, sid, mid);
+
+ sctp_intl_reap_ordered(ulpq, sid);
+}
+
+static void sctp_handle_iftsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk)
+{
+ struct sctp_ifwdtsn_skip *skip;
+
+ /* Walk through all the skipped MIDs and abort stream pd if possible */
+ sctp_walk_ifwdtsn(skip, chunk)
+ sctp_intl_skip(ulpq, ntohs(skip->stream),
+ ntohl(skip->mid), skip->flags);
+}
+
static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.data_chunk_len = sizeof(struct sctp_data_chunk),
.ftsn_chunk_len = sizeof(struct sctp_fwdtsn_chunk),
@@ -1255,6 +1302,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = {
.generate_ftsn = sctp_generate_fwdtsn,
.validate_ftsn = sctp_validate_fwdtsn,
.report_ftsn = sctp_report_fwdtsn,
+ .handle_ftsn = sctp_handle_fwdtsn,
};
static struct sctp_stream_interleave sctp_stream_interleave_1 = {
@@ -1273,6 +1321,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = {
.generate_ftsn = sctp_generate_iftsn,
.validate_ftsn = sctp_validate_iftsn,
.report_ftsn = sctp_report_iftsn,
+ .handle_ftsn = sctp_handle_iftsn,
};
void sctp_stream_interleave_init(struct sctp_stream *stream)
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 6/8] sctp: add stream interleave support in stream scheduler
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
As Marcelo said in the stream scheduler patch:
Support for I-DATA chunks, also described in RFC8260, with user message
interleaving is straightforward as it just requires the schedulers to
probe for the feature and ignore datamsg boundaries when dequeueing.
All needs to do is just to ignore datamsg boundaries when dequeueing.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/stream_sched.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sctp/stream_sched.c b/net/sctp/stream_sched.c
index d8c162a..f5fcd42 100644
--- a/net/sctp/stream_sched.c
+++ b/net/sctp/stream_sched.c
@@ -242,7 +242,8 @@ int sctp_sched_get_value(struct sctp_association *asoc, __u16 sid,
void sctp_sched_dequeue_done(struct sctp_outq *q, struct sctp_chunk *ch)
{
- if (!list_is_last(&ch->frag_list, &ch->msg->chunks)) {
+ if (!list_is_last(&ch->frag_list, &ch->msg->chunks) &&
+ !q->asoc->intl_enable) {
struct sctp_stream_out *sout;
__u16 sid;
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 7/8] sctp: update mid instead of ssn when doing stream and asoc reset
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
When using idata and doing stream and asoc reset, setting ssn with
0 could only clear the 1st 16 bits of mid.
So to make this work for both data and idata, it sets mid with 0
instead of ssn, and also mid_uo for unordered idata also need to
be cleared, as said in section 2.3.2 of RFC8260.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/stream.c | 40 +++++++++++++++++++++++++---------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index b3a9f37..06b644d 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -216,11 +216,13 @@ void sctp_stream_clear(struct sctp_stream *stream)
{
int i;
- for (i = 0; i < stream->outcnt; i++)
- stream->out[i].ssn = 0;
+ for (i = 0; i < stream->outcnt; i++) {
+ stream->out[i].mid = 0;
+ stream->out[i].mid_uo = 0;
+ }
for (i = 0; i < stream->incnt; i++)
- stream->in[i].ssn = 0;
+ stream->in[i].mid = 0;
}
void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
@@ -607,10 +609,10 @@ struct sctp_chunk *sctp_process_strreset_outreq(
}
for (i = 0; i < nums; i++)
- stream->in[ntohs(str_p[i])].ssn = 0;
+ stream->in[ntohs(str_p[i])].mid = 0;
} else {
for (i = 0; i < stream->incnt; i++)
- stream->in[i].ssn = 0;
+ stream->in[i].mid = 0;
}
result = SCTP_STRRESET_PERFORMED;
@@ -783,10 +785,12 @@ struct sctp_chunk *sctp_process_strreset_tsnreq(
/* G5: The next expected and outgoing SSNs MUST be reset to 0 for all
* incoming and outgoing streams.
*/
- for (i = 0; i < stream->outcnt; i++)
- stream->out[i].ssn = 0;
+ for (i = 0; i < stream->outcnt; i++) {
+ stream->out[i].mid = 0;
+ stream->out[i].mid_uo = 0;
+ }
for (i = 0; i < stream->incnt; i++)
- stream->in[i].ssn = 0;
+ stream->in[i].mid = 0;
result = SCTP_STRRESET_PERFORMED;
@@ -976,11 +980,15 @@ struct sctp_chunk *sctp_process_strreset_resp(
if (result == SCTP_STRRESET_PERFORMED) {
if (nums) {
- for (i = 0; i < nums; i++)
- stream->out[ntohs(str_p[i])].ssn = 0;
+ for (i = 0; i < nums; i++) {
+ stream->out[ntohs(str_p[i])].mid = 0;
+ stream->out[ntohs(str_p[i])].mid_uo = 0;
+ }
} else {
- for (i = 0; i < stream->outcnt; i++)
- stream->out[i].ssn = 0;
+ for (i = 0; i < stream->outcnt; i++) {
+ stream->out[i].mid = 0;
+ stream->out[i].mid_uo = 0;
+ }
}
flags = SCTP_STREAM_RESET_OUTGOING_SSN;
@@ -1041,10 +1049,12 @@ struct sctp_chunk *sctp_process_strreset_resp(
asoc->ctsn_ack_point = asoc->next_tsn - 1;
asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
- for (i = 0; i < stream->outcnt; i++)
- stream->out[i].ssn = 0;
+ for (i = 0; i < stream->outcnt; i++) {
+ stream->out[i].mid = 0;
+ stream->out[i].mid_uo = 0;
+ }
for (i = 0; i < stream->incnt; i++)
- stream->in[i].ssn = 0;
+ stream->in[i].mid = 0;
}
for (i = 0; i < stream->outcnt; i++)
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 8/8] sctp: support sysctl to allow users to use stream interleave
From: Xin Long @ 2017-12-12 9:25 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1513070662.git.lucien.xin@gmail.com>
This is the last patch for support of stream interleave, after this patch,
users could enable stream interleave by systcl -w net.sctp.intl_enable=1.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/sctp/sysctl.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index ef7ca44..33ca5b7 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -289,6 +289,13 @@ static struct ctl_table sctp_net_table[] = {
.proc_handler = proc_sctp_do_auth,
},
{
+ .procname = "intl_enable",
+ .data = &init_net.sctp.intl_enable,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+ {
.procname = "addr_scope_policy",
.data = &init_net.sctp.scope_policy,
.maxlen = sizeof(int),
--
2.1.0
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: vf610-zii-dev: use XAUI for DSA link ports
From: Russell King @ 2017-12-12 9:29 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Mark Rutland,
netdev-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Sascha Hauer,
Shawn Guo, Stefan Agner, Vivien Didelot
Use XAUI rather than XGMII for DSA link ports, as this is the interface
mode that the switches actually use. XAUI is the 4 lane bus with clock
per direction, whereas XGMII is a 32 bit bus with clock.
Signed-off-by: Russell King <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org>
---
This must be applied along with patch 1 to avoid breakage.
arch/arm/boot/dts/vf610-zii-dev-rev-c.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
index 1b102c7f7928..4a972fceb3b5 100644
--- a/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
+++ b/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts
@@ -128,7 +128,7 @@
switch0port10: port@10 {
reg = <10>;
label = "dsa";
- phy-mode = "xgmii";
+ phy-mode = "xaui";
link = <&switch1port10>;
};
};
@@ -233,7 +233,7 @@
switch1port10: port@10 {
reg = <10>;
label = "dsa";
- phy-mode = "xgmii";
+ phy-mode = "xaui";
link = <&switch0port10>;
};
};
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/2] net: dsa: allow XAUI phy interface mode
From: Russell King @ 2017-12-12 9:29 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: devicetree, linux-arm-kernel, Mark Rutland, netdev, Rob Herring,
Sascha Hauer, Shawn Guo, Stefan Agner, Vivien Didelot
XGMII is a 32-bit bus plus two clock signals per direction. XAUI is
four serial lanes per direction. The 88e6190 supports XAUI but not
XGMII as it doesn't have enough pins. The same is true of 88e6176.
Match on PHY_INTERFACE_MODE_XAUI for the XAUI port type, but keep
accepting XGMII for backwards compatibility.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
drivers/net/dsa/mv88e6xxx/port.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index a7801f6668a5..6315774d72b3 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -338,6 +338,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
cmode = MV88E6XXX_PORT_STS_CMODE_2500BASEX;
break;
case PHY_INTERFACE_MODE_XGMII:
+ case PHY_INTERFACE_MODE_XAUI:
cmode = MV88E6XXX_PORT_STS_CMODE_XAUI;
break;
case PHY_INTERFACE_MODE_RXAUI:
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net-next v5 1/2] net: add support for Cavium PTP coprocessor
From: Aleksey Makarov @ 2017-12-12 9:41 UTC (permalink / raw)
To: Richard Cochran
Cc: netdev, linux-arm-kernel, linux-kernel, Goutham, Sunil,
Radoslaw Biernacki, Robert Richter, David Daney,
Philippe Ombredanne
In-Reply-To: <20171211225954.ezqut6jvfg65rg4w@localhost>
Hi Richard,
On 12/12/2017 01:59 AM, Richard Cochran wrote:
>
> Sorry I didn't finish reviewing before...
>
> On Mon, Dec 11, 2017 at 05:14:30PM +0300, Aleksey Makarov wrote:
[ ... ]
>> +static int cavium_ptp_probe(struct pci_dev *pdev,
>> + const struct pci_device_id *ent)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct cavium_ptp *clock;
>> + struct cyclecounter *cc;
>> + u64 clock_cfg;
>> + u64 clock_comp;
>> + int err;
>> +
>> + clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
>> + if (!clock)
>> + return -ENOMEM;
>> +
>> + clock->pdev = pdev;
>> +
>> + err = pcim_enable_device(pdev);
>> + if (err)
>> + return err;
>> +
>> + err = pcim_iomap_regions(pdev, 1 << PCI_PTP_BAR_NO, pci_name(pdev));
>> + if (err)
>> + return err;
>> +
>> + clock->reg_base = pcim_iomap_table(pdev)[PCI_PTP_BAR_NO];
>> +
>> + spin_lock_init(&clock->spin_lock);
>> +
>> + cc = &clock->cycle_counter;
>> + cc->read = cavium_ptp_cc_read;
>> + cc->mask = CYCLECOUNTER_MASK(64);
>> + cc->mult = 1;
>> + cc->shift = 0;
>> +
>> + timecounter_init(&clock->time_counter, &clock->cycle_counter,
>> + ktime_to_ns(ktime_get_real()));
>> +
>> + clock->clock_rate = ptp_cavium_clock_get();
>> +
>> + clock->ptp_info = (struct ptp_clock_info) {
>> + .owner = THIS_MODULE,
>> + .name = "ThunderX PTP",
>> + .max_adj = 1000000000ull,
>> + .n_ext_ts = 0,
>> + .n_pins = 0,
>> + .pps = 0,
>> + .adjfreq = cavium_ptp_adjfreq,
>> + .adjtime = cavium_ptp_adjtime,
>> + .gettime64 = cavium_ptp_gettime,
>> + .settime64 = cavium_ptp_settime,
>> + .enable = cavium_ptp_enable,
>> + };
>> +
>> + clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG);
>> + clock_cfg |= PTP_CLOCK_CFG_PTP_EN;
>> + writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG);
>> +
>> + clock_comp = ((u64)1000000000ull << 32) / clock->clock_rate;
>> + writeq(clock_comp, clock->reg_base + PTP_CLOCK_COMP);
>> +
>> + clock->ptp_clock = ptp_clock_register(&clock->ptp_info, dev);
>> + if (IS_ERR(clock->ptp_clock)) {
>
> You need to handle the case when ptp_clock_register() returns NULL.
>
> from ptp_clock_kernel.h:
>
> /**
> * ptp_clock_register() - register a PTP hardware clock driver
> *
> * @info: Structure describing the new clock.
> * @parent: Pointer to the parent device of the new clock.
> *
> * Returns a valid pointer on success or PTR_ERR on failure. If PHC
> * support is missing at the configuration level, this function
> * returns NULL, and drivers are expected to gracefully handle that
> * case separately.
> */
If ptp_clock_register() returns NULL, the device is still paired with the driver,
but the driver is not registered in the PTP core. When ethernet driver needs
the reference to this cavium PTP driver, it calls cavium_ptp_get() that checks
if ptp->ptp_clock is NULL and, if so, returns -ENODEV.
I need this behavior because I need to differentiate between two cases:
- the state when the driver is not initialized for the device because of PTP core
has not registered it. In this case function cavium_ptp_get() returns -ENODEV
and ethernet driver proceeds without PTP device.
- the state when the driver is not initialized because kernel has not tired
to initialize it yet. In this case function cavium_ptp_get() returns -EPROBE_DEFER
that is used in ethernet driver to defer initialization.
If you know how to do the same in more smoothly please share it. Or else I would
prefer to insert a comment about it and leave it as is.
Richard, thank you for review. I am going to address your comments in my next series.
Thank you
Aleksey Makarov
>> + clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG);
>> + clock_cfg &= ~PTP_CLOCK_CFG_PTP_EN;
>> + writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG);
>> + return PTR_ERR(clock->ptp_clock);
>> + }
>> +
>> + pci_set_drvdata(pdev, clock);
>> + return 0;
>> +}
>
> Thanks,
> Richard
>
^ permalink raw reply
* Re: [PATCH net v2 7/9] net: aquantia: Reset driver level statistics to zero on initialization
From: Igor Russkikh @ 2017-12-12 9:46 UTC (permalink / raw)
To: Andrew Lunn
Cc: David S . Miller, netdev, David Arcari, Pavel Belous,
Nadezhda Krupnina, Simon Edelhaus
In-Reply-To: <20171211155156.GK28672@lunn.ch>
>> --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
>> +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
>> @@ -344,6 +344,13 @@ static int hw_atl_a0_hw_init(struct aq_hw_s *self,
>> hw_atl_a0_hw_rss_set(self, &aq_nic_cfg->aq_rss);
>> hw_atl_a0_hw_rss_hash_set(self, &aq_nic_cfg->aq_rss);
>>
>> + /* Read initial hardware counters
>> + * and reset current in-driver statistics
>> + */
>> + hw_atl_utils_update_stats(self);
>> + memset(&PHAL_ATLANTIC_A0->curr_stats, 0,
>> + sizeof(PHAL_ATLANTIC_A0->curr_stats));
>> +
>> err = aq_hw_err_from_flags(self);
>> if (err < 0)
>> goto err_exit;
> Hi Igor
>
> It looks like this is called on pm state change? Does this mean that
> resume will zero the statistics? That is probably not what you want.
>
> You should probably only clear the statics in the probe function.
>
Hi Andrew, thanks for the review. It seems you are right and this'll reset stats on PM state. I'll revalidate this
and come back with updated patch.
BR, Igor
^ permalink raw reply
* Re: [PATCH v5 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
From: Daniel Lezcano @ 2017-12-12 10:05 UTC (permalink / raw)
To: Rick Chen, rick, linux-kernel, arnd, linus.walleij, linux-arch,
tglx, jason, marc.zyngier, robh+dt, netdev, deanbo422, devicetree,
viro, dhowells, will.deacon, linux-serial
Cc: Greentime Hu
In-Reply-To: <1513057621-19084-2-git-send-email-rickchen36@gmail.com>
On 12/12/2017 06:46, Rick Chen wrote:
> ATCPIT100 is often used on the Andes architecture,
> This timer provide 4 PIT channels. Each PIT channel is a
> multi-function timer, can be configured as 32,16,8 bit timers
> or PWM as well.
>
> For system timer it will set channel 1 32-bit timer0 as clock
> source and count downwards until underflow and restart again.
[ ... ]
> +config CLKSRC_ATCPIT100
> + bool "Clocksource for AE3XX platform"
> + depends on NDS32 || COMPILE_TEST
> + depends on HAS_IOMEM
> + help
> + This option enables support for the Andestech AE3XX platform timers.
Hi Rick,
the general rule for the Kconfig is:
bool "Clocksource for AE3XX platform" if COMPILE_TEST
and no deps on the platform.
It is up to the platform Kconfig to select the option.
We want here a silent option but make it selectable in case of
compilation test coverage.
Also, this driver is not a CLKSRC but a TIMER. Rename CLKSRC_ATCPIT100
to TIMER_ATCPIT100.
> +
> endmenu
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 72711f1..7d072f5 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -75,3 +75,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
> obj-$(CONFIG_H8300_TPU) += h8300_tpu.o
> obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
> obj-$(CONFIG_X86_NUMACHIP) += numachip.o
> +obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o
[ ... ]
> +static struct timer_of to = {
> + .flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE,
> +
> + .clkevt = {
> + .name = "atcpit100_tick",
> + .rating = 300,
> + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> + .set_state_shutdown = atcpit100_clkevt_shutdown,
> + .set_state_periodic = atcpit100_clkevt_set_periodic,
> + .set_state_oneshot = atcpit100_clkevt_set_oneshot,
> + .tick_resume = atcpit100_clkevt_shutdown,
> + .set_next_event = atcpit100_clkevt_next_event,
> + .cpumask = cpu_all_mask,
You may consider CLOCK_EVT_DYN_IRQ
https://lwn.net/Articles/540160/
> + },
> +
> + .of_irq = {
> + .handler = atcpit100_timer_interrupt,
> + .flags = IRQF_TIMER | IRQF_IRQPOLL,
> + },
> +
> + /*
> + * FIXME: we currently only support clocking using PCLK
> + * and using EXTCLK is not supported in the driver.
> + */
> + .of_clk = {
> + .name = "PCLK",
> + }
What do you mean ? We can't specify several clock names with timer-of?
--
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
^ 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