Netdev List
 help / color / mirror / Atom feed
* Re: [RFC 2/2] xen-netback: disable multicast and use a random hw MAC address
From: Bill Fink @ 2014-02-12 17:17 UTC (permalink / raw)
  To: Ian Campbell
  Cc: Luis R. Rodriguez, netdev@vger.kernel.org, xen-devel,
	Paul Durrant, Wei Liu, kvm, linux-kernel@vger.kernel.org
In-Reply-To: <1392203708.13563.50.camel@kazak.uk.xensource.com>

On Wed, 12 Feb 2014, Ian Campbell wrote:

> On Tue, 2014-02-11 at 13:53 -0800, Luis R. Rodriguez wrote:
> > Cc'ing kvm folks as they may have a shared interest on the shared
> > physical case with the bridge (non NAT).
> > 
> > On Tue, Feb 11, 2014 at 12:43 AM, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> > > On Mon, 2014-02-10 at 14:29 -0800, Luis R. Rodriguez wrote:
> > >> From: "Luis R. Rodriguez" <mcgrof@suse.com>
> > >>
> > >> Although the xen-netback interfaces do not participate in the
> > >> link as a typical Ethernet device interfaces for them are
> > >> still required under the current archtitecture. IPv6 addresses
> > >> do not need to be created or assigned on the xen-netback interfaces
> > >> however, even if the frontend devices do need them, so clear the
> > >> multicast flag to ensure the net core does not initiate IPv6
> > >> Stateless Address Autoconfiguration.
> > >
> > > How does disabling SAA flow from the absence of multicast?
> > 
> > See patch 1 in this series [0], but I explain the issue I see with
> > this on the cover letter [1].
> 
> Oop, I felt like I'd missed some context. Thanks for pointing out that
> it was right under my nose.
> 
> > In summary the RFCs on IPv6 make it
> > clear you need multicast for Stateless address autoconfiguration
> > (SLAAC is the preferred acronym) and DAD,
> 
> That seems reasonable, but I think is the opposite to what I was trying
> to get at.
> 
> Why is it not possible to disable SLAAC and/or DAD even if multicast is
> present?
> 
> IOW -- enabling/disabling multicast seems to me to be an odd proxy for
> disabling SLAAC or DAD and AIUI your patch fixes the opposite case,
> which is to avoid SLAAC and DAD on interfaces which don't do multicast
> (which makes sense since those protocols involve multicast).

Forgive me if this doesn't make sense in this context since
I'm not a kernel developer, but I was just wondering if any of
the sysctls:

	/proc/sys/net/ipv6/conf/<ifc>/disable_ipv6
	/proc/sys/net/ipv6/conf/<ifc>/accept_dad
	/proc/sys/net/ipv6/conf/<ifc>/accept_ra
	/proc/sys/net/ipv6/conf/<ifc>/autoconf

would be apropos for the requirement being discussed.

					-Bill

^ permalink raw reply

* Re: [PATCH v3 0/2] ASoC: atmel_ssc_dai: add option to choose clock
From: Mark Brown @ 2014-02-12 17:23 UTC (permalink / raw)
  To: Bo Shen
  Cc: Mark Rutland, alsa-devel, Stephen Warren, linux-doc, Takashi Iwai,
	nicolas.ferre, Liam Girdwood, Chas Williams, Lars-Peter Clausen,
	Arnd Bergmann, linux-atm-general, plagnioj, devicetree,
	Pawel Moll, Ian Campbell, linux-sound, Rob Herring,
	linux-arm-kernel, Richard Genoud, Greg Kroah-Hartman,
	linux-kernel, Rob Landley, netdev
In-Reply-To: <1392012586-30790-1-git-send-email-voice.shen@atmel.com>


[-- Attachment #1.1: Type: text/plain, Size: 259 bytes --]

On Mon, Feb 10, 2014 at 02:09:44PM +0800, Bo Shen wrote:
> When SSC work in slave mode, the clock can come from TK pin and also
> can come from RK pin, this is hardware design decided. So, make it
> available to choose where the clock from.

Applied, thanks.

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* [PATCH] staging: r8188eu: Fix Smatch warnings
From: Larry Finger @ 2014-02-12 17:27 UTC (permalink / raw)
  To: gregkh; +Cc: devel, netdev, Dan Carpenter, Larry Finger

Smatch reports the following:

core/rtw_ieee80211.c:489 rtw_get_wpa_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:491 rtw_get_wpa_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:493 rtw_get_wpa_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:495 rtw_get_wpa_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:497 rtw_get_wpa_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:505 rtw_get_wpa2_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:507 rtw_get_wpa2_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:509 rtw_get_wpa2_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:511 rtw_get_wpa2_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:513 rtw_get_wpa2_cipher_suite() warn: add some parenthesis here?
core/rtw_ieee80211.c:534 rtw_parse_wpa_ie() warn: add some parenthesis here?
core/rtw_ieee80211.c:579 rtw_parse_wpa_ie() warn: add some parenthesis here?
core/rtw_ieee80211.c:649 rtw_parse_wpa2_ie() warn: add some parenthesis here?
core/rtw_ieee80211.c:803 rtw_get_wps_attr() warn: add some parenthesis here?
core/rtw_ieee80211.c:1213 rtw_get_p2p_ie() warn: add some parenthesis here?
core/rtw_ieee80211.c:1248 rtw_get_p2p_attr() warn: add some parenthesis here?
core/rtw_mlme.c:258 _rtw_find_network() warn: add some parenthesis here?
core/rtw_mlme.c:1581 rtw_check_join_candidate() warn: this array is probably non-NULL. 'pmlmepriv->assoc_ssid.Ssid'
core/rtw_mlme.c:1843 SecIsInPMKIDList() warn: add some parenthesis here?
core/rtw_mlme_ext.c:4189 on_action_public_vendor() warn: add some parenthesis here?
core/rtw_recv.c:1157 validate_recv_mgnt_frame() warn: add some parenthesis here?
core/rtw_xmit.c:671 xmitframe_addmic() warn: add some parenthesis here?
hal/rtl8188e_mp.c:206 Hal_MPT_CCKTxPowerAdjustbyIndex() error: buffer overflow 'CCKSwingTable_Ch1_Ch13' 33 <= 255
hal/rtl8188e_mp.c:215 Hal_MPT_CCKTxPowerAdjustbyIndex() error: buffer overflow 'CCKSwingTable_Ch14' 33 <= 255

Not listed here is one remaining buffer overflow message that I believe to be an error in Smatch.

These warnings were reported by the 0-DAY kernel build testing backend.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
---
 drivers/staging/rtl8188eu/core/rtw_ieee80211.c | 32 +++++++++++++-------------
 drivers/staging/rtl8188eu/core/rtw_mlme.c      |  6 ++---
 drivers/staging/rtl8188eu/core/rtw_mlme_ext.c  |  2 +-
 drivers/staging/rtl8188eu/core/rtw_recv.c      |  3 ++-
 drivers/staging/rtl8188eu/core/rtw_xmit.c      |  2 +-
 drivers/staging/rtl8188eu/hal/rtl8188e_mp.c    |  2 ++
 6 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
index d779c80..4076c66 100644
--- a/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8188eu/core/rtw_ieee80211.c
@@ -486,15 +486,15 @@ unsigned char *rtw_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit)
 
 int rtw_get_wpa_cipher_suite(u8 *s)
 {
-	if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN) == true)
+	if (!memcmp(s, WPA_CIPHER_SUITE_NONE, WPA_SELECTOR_LEN))
 		return WPA_CIPHER_NONE;
-	if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN) == true)
+	if (!memcmp(s, WPA_CIPHER_SUITE_WEP40, WPA_SELECTOR_LEN))
 		return WPA_CIPHER_WEP40;
-	if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN) == true)
+	if (!memcmp(s, WPA_CIPHER_SUITE_TKIP, WPA_SELECTOR_LEN))
 		return WPA_CIPHER_TKIP;
-	if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN) == true)
+	if (!memcmp(s, WPA_CIPHER_SUITE_CCMP, WPA_SELECTOR_LEN))
 		return WPA_CIPHER_CCMP;
-	if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN) == true)
+	if (!memcmp(s, WPA_CIPHER_SUITE_WEP104, WPA_SELECTOR_LEN))
 		return WPA_CIPHER_WEP104;
 
 	return 0;
@@ -502,15 +502,15 @@ int rtw_get_wpa_cipher_suite(u8 *s)
 
 int rtw_get_wpa2_cipher_suite(u8 *s)
 {
-	if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN) == true)
+	if (!memcmp(s, RSN_CIPHER_SUITE_NONE, RSN_SELECTOR_LEN))
 		return WPA_CIPHER_NONE;
-	if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN) == true)
+	if (!memcmp(s, RSN_CIPHER_SUITE_WEP40, RSN_SELECTOR_LEN))
 		return WPA_CIPHER_WEP40;
-	if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN) == true)
+	if (!memcmp(s, RSN_CIPHER_SUITE_TKIP, RSN_SELECTOR_LEN))
 		return WPA_CIPHER_TKIP;
-	if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN) == true)
+	if (!memcmp(s, RSN_CIPHER_SUITE_CCMP, RSN_SELECTOR_LEN))
 		return WPA_CIPHER_CCMP;
-	if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN) == true)
+	if (!memcmp(s, RSN_CIPHER_SUITE_WEP104, RSN_SELECTOR_LEN))
 		return WPA_CIPHER_WEP104;
 
 	return 0;
@@ -531,7 +531,7 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwis
 
 
 	if ((*wpa_ie != _WPA_IE_ID_) || (*(wpa_ie+1) != (u8)(wpa_ie_len - 2)) ||
-	    (!memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN) != true))
+	    (memcmp(wpa_ie+2, RTW_WPA_OUI_TYPE, WPA_SELECTOR_LEN)))
 		return _FAIL;
 
 	pos = wpa_ie;
@@ -576,7 +576,7 @@ int rtw_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher, int *pairwis
 	if (is_8021x) {
 		if (left >= 6) {
 			pos += 2;
-			if (!memcmp(pos, SUITE_1X, 4) == 1) {
+			if (!memcmp(pos, SUITE_1X, 4)) {
 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s : there has 802.1x auth\n", __func__));
 				*is_8021x = 1;
 			}
@@ -646,7 +646,7 @@ int rtw_parse_wpa2_ie(u8 *rsn_ie, int rsn_ie_len, int *group_cipher, int *pairwi
 	if (is_8021x) {
 		if (left >= 6) {
 			pos += 2;
-			if (!memcmp(pos, SUITE_1X, 4) == 1) {
+			if (!memcmp(pos, SUITE_1X, 4)) {
 				RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, ("%s (): there has 802.1x auth\n", __func__));
 				*is_8021x = 1;
 			}
@@ -800,7 +800,7 @@ u8 *rtw_get_wps_attr(u8 *wps_ie, uint wps_ielen, u16 target_attr_id , u8 *buf_at
 		*len_attr = 0;
 
 	if ((wps_ie[0] != _VENDOR_SPECIFIC_IE_) ||
-	    (!memcmp(wps_ie + 2, wps_oui , 4) != true))
+	    (memcmp(wps_ie + 2, wps_oui , 4)))
 		return attr_ptr;
 
 	/*  6 = 1(Element ID) + 1(Length) + 4(WPS OUI) */
@@ -1210,7 +1210,7 @@ u8 *rtw_get_p2p_ie(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen)
 			dump_stack();
 			return NULL;
 		}
-		if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&in_ie[cnt+2], p2p_oui, 4) == true)) {
+		if ((eid == _VENDOR_SPECIFIC_IE_) && (!memcmp(&in_ie[cnt+2], p2p_oui, 4))) {
 			p2p_ie_ptr = in_ie + cnt;
 
 			if (p2p_ie != NULL)
@@ -1245,7 +1245,7 @@ u8 *rtw_get_p2p_attr(u8 *p2p_ie, uint p2p_ielen, u8 target_attr_id , u8 *buf_att
 		*len_attr = 0;
 
 	if (!p2p_ie || (p2p_ie[0] != _VENDOR_SPECIFIC_IE_) ||
-	    (!memcmp(p2p_ie + 2, p2p_oui , 4) != true))
+	    (memcmp(p2p_ie + 2, p2p_oui , 4)))
 		return attr_ptr;
 
 	/*  6 = 1(Element ID) + 1(Length) + 3 (OUI) + 1(OUI Type) */
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c b/drivers/staging/rtl8188eu/core/rtw_mlme.c
index 260da41..a934bd9 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c
@@ -255,7 +255,7 @@ struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr)
 
 	while (plist != phead) {
 		pnetwork = container_of(plist, struct wlan_network , list);
-		if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN) == true)
+		if (!memcmp(addr, pnetwork->network.MacAddress, ETH_ALEN))
 			break;
 		plist = plist->next;
 	}
@@ -1578,7 +1578,7 @@ static int rtw_check_join_candidate(struct mlme_priv *pmlmepriv
 	}
 
 	/* check ssid, if needed */
-	if (pmlmepriv->assoc_ssid.Ssid && pmlmepriv->assoc_ssid.SsidLength) {
+	if (pmlmepriv->assoc_ssid.SsidLength) {
 		if (competitor->network.Ssid.SsidLength != pmlmepriv->assoc_ssid.SsidLength ||
 		    !memcmp(competitor->network.Ssid.Ssid, pmlmepriv->assoc_ssid.Ssid, pmlmepriv->assoc_ssid.SsidLength) == false)
 			goto exit;
@@ -1840,7 +1840,7 @@ static int SecIsInPMKIDList(struct adapter *Adapter, u8 *bssid)
 
 	do {
 		if ((psecuritypriv->PMKIDList[i].bUsed) &&
-		    (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN) == true)) {
+		    (!memcmp(psecuritypriv->PMKIDList[i].Bssid, bssid, ETH_ALEN))) {
 			break;
 		} else {
 			i++;
diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
index b84610f..301cda5 100644
--- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c
@@ -4186,7 +4186,7 @@ static unsigned int on_action_public_vendor(union recv_frame *precv_frame)
 	u8 *pframe = precv_frame->u.hdr.rx_data;
 	u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
 
-	if (!memcmp(frame_body + 2, P2P_OUI, 4) == true)
+	if (!memcmp(frame_body + 2, P2P_OUI, 4))
 		ret = on_action_public_p2p(precv_frame);
 
 	return ret;
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 94d320b..35397bd 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -1154,7 +1154,8 @@ static int validate_recv_mgnt_frame(struct adapter *padapter,
 		} else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ) {
 			psta->sta_stats.rx_probereq_pkts++;
 		} else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
-			if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN) == true)
+			if (!memcmp(padapter->eeprompriv.mac_addr,
+				    GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN))
 				psta->sta_stats.rx_probersp_pkts++;
 			else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)) ||
 				 is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
diff --git a/drivers/staging/rtl8188eu/core/rtw_xmit.c b/drivers/staging/rtl8188eu/core/rtw_xmit.c
index 44e54a3..4475ed4 100644
--- a/drivers/staging/rtl8188eu/core/rtw_xmit.c
+++ b/drivers/staging/rtl8188eu/core/rtw_xmit.c
@@ -668,7 +668,7 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr
 				/* start to calculate the mic code */
 				rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
 			} else {
-				if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16) == true) {
+				if (!memcmp(&stainfo->dot11tkiptxmickey.skey[0], null_key, 16)) {
 					/* DbgPrint("\nxmitframe_addmic:stainfo->dot11tkiptxmickey == 0\n"); */
 					/* msleep(10); */
 					return _FAIL;
diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c b/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c
index cd2027b..cc71784 100644
--- a/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c
+++ b/drivers/staging/rtl8188eu/hal/rtl8188e_mp.c
@@ -201,6 +201,8 @@ void Hal_MPT_CCKTxPowerAdjustbyIndex(struct adapter *pAdapter, bool beven)
 		else
 			CCK_index = CCK_index_old + 1;
 
+		if (CCK_index > 32)
+			CCK_index = 32;
 		/* Adjust CCK according to gain index */
 		if (!pDM_Odm->RFCalibrateInfo.bCCKinCH14) {
 			rtw_write8(pAdapter, 0xa22, CCKSwingTable_Ch1_Ch13[CCK_index][0]);
-- 
1.8.4.5

^ permalink raw reply related

* [PATCH] ipv4: arp: process only if ipv4 address configured
From: Florian Westphal @ 2014-02-12 17:27 UTC (permalink / raw)
  To: netdev; +Cc: Florian Westphal

8030f54499925d073a88c09f ([IPV4] devinet: Register inetdev earlier.)
changed arp behaviour (2.6.22 onwards).

Before this, inetdev_init() was called only when the first address was
added to the interface, i.e. arp_process always dropped incoming arp
packets as __in_dev_get_rcu() returned NULL when no IP address was set
on the interface.

With >= 2.6.22 we now process arp packets even if no address is assigned.
It can cause issues if the machine has several interfaces in the same
segment; requests receive answers from multiple macs.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
IMO such configurations are just asking for trouble, but it used
to work on older kernels.  Do we care about such setups?

diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 1a9b99e..8a44ed2 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -738,7 +738,7 @@ static int arp_process(struct sk_buff *skb)
 	 * is ARP'able.
 	 */
 
-	if (in_dev == NULL)
+	if (in_dev == NULL || in_dev->ifa_list == NULL)
 		goto out;
 
 	arp = arp_hdr(skb);
-- 
1.8.1.5

^ permalink raw reply related

* Re: [PATCH net 1/3] kref: add kref_sub_return
From: Michael S. Tsirkin @ 2014-02-12 17:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: linux-kernel, Jason Wang, virtio-dev, virtualization, netdev,
	davem, qinchuanyu, Joern Engel, Anatol Pomozov,
	Nicholas Bellinger
In-Reply-To: <20140212165630.GA22991@kroah.com>

On Wed, Feb 12, 2014 at 08:56:30AM -0800, Greg Kroah-Hartman wrote:
> On Wed, Feb 12, 2014 at 06:38:21PM +0200, Michael S. Tsirkin wrote:
> > It is sometimes useful to get the value of the reference count after
> > decrement.
> > For example, vhost wants to execute some periodic cleanup operations
> > once number of references drops below a specific value, before it
> > reaches zero (for efficiency).
> 
> You should never care about what the value of the kref is, if you are
> using it correctly :)
> 
> So I really don't want to add this function, as I'm sure people will use
> it incorrectly.  You should only care if the reference drops to 0, if
> not, then your usage doesn't really fit into the "kref" model, and so,
> just use an atomic variable.

This happens when you have code that keeps
reference itself implicitly or explicitly.

	foo(struct kref *k, int bar) {

	sub = kref_sub(k)

	if (sub == 1)
		FOO(k, bar) /* Here I am the only one
			       with a reference */

	}

	kref_get(k)
	foo(k, bar);
	....
	kref_put(k)

Why not do FOO in destructor you ask?
Absolutely but this will be called much later.

Maybe you will reconsider if I document this
as the only legal use?

> 
> I really want to know why it matters for "efficiency" that you know this
> number.  How does that help anything, as the number could then go up
> later on, and the work you did at a "lower" number is obsolete, right?
> 
> thanks,
> 
> greg k-h

The issue is that if number dropped to 1, this means
we must do the cleanup work since there are
no outstanding buffers, (last user is ourselves)
if we do not cleanup,
guest will hang waiting for us.

But it never drops to 0 since we have our own reference
in the device.
If it goes up again this means we didn't have
to do cleanup, but an alternative is doing
it all the time and that is slow.

Yes I can rework vhost to open-code this kref use, it's
no big deal.
Alternatively since most of the use does match kref
model, maybe __kref_sub_return with disclaimers
that you must know what you are doing?
Please let me know.

Thanks!

-- 
MST

^ permalink raw reply

* Re: [PATCH] ipv4: arp: process only if ipv4 address configured
From: Eric Dumazet @ 2014-02-12 18:26 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netdev
In-Reply-To: <1392226067-21736-1-git-send-email-fw@strlen.de>

On Wed, 2014-02-12 at 18:27 +0100, Florian Westphal wrote:
> 8030f54499925d073a88c09f ([IPV4] devinet: Register inetdev earlier.)
> changed arp behaviour (2.6.22 onwards).
> 
> Before this, inetdev_init() was called only when the first address was
> added to the interface, i.e. arp_process always dropped incoming arp
> packets as __in_dev_get_rcu() returned NULL when no IP address was set
> on the interface.
> 
> With >= 2.6.22 we now process arp packets even if no address is assigned.
> It can cause issues if the machine has several interfaces in the same
> segment; requests receive answers from multiple macs.


What about arp_filter value/meaning ?

^ permalink raw reply

* [PATCH net-next 00/14] tipc: clean up media and bearer layer
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion

This commit series aims at facilitating future changes to the
locking policy around nodes, links and bearers.

Currently, we have a big read/write lock (net_lock) that is used for
serializing all changes to the node, link and bearer lists, as well
as to their mutual pointers and references.

But, in order to allow for concurrent access to the contents of these
structures, net_lock is only used in read mode by the data path code,
and hence a finer granular locking policy must be applied inside the
scope of net_lock: a spinlock (node_lock) for each node structure,
and another one (bearer_lock) for protection of bearer structures.

This locking policy has proved hard to maintain. We have several 
times encountered contention problems between node_lock and 
bearer_lock, and with the advent of the RCU locking mechanism we
feel it is anyway obsolete and ripe for improvements.

We now plan to replace net_lock with an RCU lock, as well as
getting rid of bearer_lock altogether. This will both reduce data
path overhead and make the code more manageable, while reducing the
risk of future lock contention problems.

Prior to these changes, we need to do some necessary cleanup and
code consolidation. This is what we do with this commit series,
before we finally remove bearer_lock. In a later series we will
replace net_lock with an RCU lock.


Jon Maloy (9):
  tipc: stricter behavior of message reassembly function
  tipc: change reception of tunnelled duplicate packets
  tipc: change reception of tunnelled failover packets
  tipc: change signature of tunnelling reception function
  tipc: more cleanup of tunnelling reception function
  tipc: rename stack variables in function tipc_link_tunnel_rcv
  tipc: changes to general packet reception algorithm
  tipc: delay delete of link when failover is needed
  tipc: add node_lock protection to link lookup function

Ying Xue (5):
  tipc: move code for resetting links from bearer.c to link.c
  tipc: move code for deleting links from bearer.c to link.c
  tipc: redefine 'started' flag in struct link to bitmap
  tipc: remove 'links' list from tipc_bearer struct
  tipc: remove bearer_lock from tipc_bearer struct

 net/tipc/bcast.c  |    7 +-
 net/tipc/bearer.c |   42 ++----
 net/tipc/bearer.h |    7 +-
 net/tipc/core.c   |    2 +-
 net/tipc/link.c   |  433 ++++++++++++++++++++++++++++++-----------------------
 net/tipc/link.h   |   34 ++---
 net/tipc/node.c   |    8 +-
 7 files changed, 283 insertions(+), 250 deletions(-)

-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply

* [PATCH net-next 01/14] tipc: stricter behavior of message reassembly function
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

The function tipc_link_recv_fragment(struct sk_buff **buf) currently
leaves the value of the input buffer pointer undefined when it returns,
except when the return code indicates that the reassembly is complete.
This despite the fact that it always consumes the input buffer.

Here, we enforce a stricter behavior by this function, ensuring that
the returned buffer pointer is non-NULL if and only if the reassembly
is complete. This makes it possible to test for the buffer pointer as
criteria for successful reassembly.

We also rename the function to tipc_link_frag_rcv(), which is both
shorter and more in line with common naming practice in the network
subsystem.

Apart from the new name, these changes have no impact on current
users of the function, but makes it more practical for use in some
planned future commits.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/bcast.c |    6 +++---
 net/tipc/link.c  |   16 +++++++++-------
 net/tipc/link.h  |    6 +++---
 3 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index bf860d9..af35f76 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -481,9 +481,9 @@ receive:
 			tipc_link_recv_bundle(buf);
 		} else if (msg_user(msg) == MSG_FRAGMENTER) {
 			int ret;
-			ret = tipc_link_recv_fragment(&node->bclink.reasm_head,
-						      &node->bclink.reasm_tail,
-						      &buf);
+			ret = tipc_link_frag_rcv(&node->bclink.reasm_head,
+						 &node->bclink.reasm_tail,
+						 &buf);
 			if (ret == LINK_REASM_ERROR)
 				goto unlock;
 			spin_lock_bh(&bc_lock);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d4b5de4..17fbd15 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1584,9 +1584,9 @@ deliver:
 			continue;
 		case MSG_FRAGMENTER:
 			l_ptr->stats.recv_fragments++;
-			ret = tipc_link_recv_fragment(&l_ptr->reasm_head,
-						      &l_ptr->reasm_tail,
-						      &buf);
+			ret = tipc_link_frag_rcv(&l_ptr->reasm_head,
+						 &l_ptr->reasm_tail,
+						 &buf);
 			if (ret == LINK_REASM_COMPLETE) {
 				l_ptr->stats.recv_fragmented++;
 				msg = buf_msg(buf);
@@ -2277,12 +2277,11 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
 	return dsz;
 }
 
-/*
- * tipc_link_recv_fragment(): Called with node lock on. Returns
+/* tipc_link_frag_rcv(): Called with node lock on. Returns
  * the reassembled buffer if message is complete.
  */
-int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
-			    struct sk_buff **fbuf)
+int tipc_link_frag_rcv(struct sk_buff **head, struct sk_buff **tail,
+		       struct sk_buff **fbuf)
 {
 	struct sk_buff *frag = *fbuf;
 	struct tipc_msg *msg = buf_msg(frag);
@@ -2296,6 +2295,7 @@ int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
 			goto out_free;
 		*head = frag;
 		skb_frag_list_init(*head);
+		*fbuf = NULL;
 		return 0;
 	} else if (*head &&
 		   skb_try_coalesce(*head, frag, &headstolen, &delta)) {
@@ -2315,10 +2315,12 @@ int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
 		*tail = *head = NULL;
 		return LINK_REASM_COMPLETE;
 	}
+	*fbuf = NULL;
 	return 0;
 out_free:
 	pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
 	kfree_skb(*fbuf);
+	*fbuf = NULL;
 	return LINK_REASM_ERROR;
 }
 
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 3b6aa65..8addc5e 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -239,9 +239,9 @@ int tipc_link_send_sections_fast(struct tipc_port *sender,
 				 struct iovec const *msg_sect,
 				 unsigned int len, u32 destnode);
 void tipc_link_recv_bundle(struct sk_buff *buf);
-int  tipc_link_recv_fragment(struct sk_buff **reasm_head,
-			     struct sk_buff **reasm_tail,
-			     struct sk_buff **fbuf);
+int  tipc_link_frag_rcv(struct sk_buff **reasm_head,
+			struct sk_buff **reasm_tail,
+			struct sk_buff **fbuf);
 void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, int prob,
 			      u32 gap, u32 tolerance, u32 priority,
 			      u32 acked_mtu);
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 02/14] tipc: move code for resetting links from bearer.c to link.c
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

From: Ying Xue <ying.xue@windriver.com>

We break out the code for resetting attached links in the
function tipc_reset_bearer(), and define a new function named
tipc_link_reset_list() to do this job.

This commit incurs no functional changes, but makes the code
of function tipc_reset_bearer() cleaner. It is also a preparation
for a more important change to the bearer code, in a subsequent
commit in this series.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/bearer.c |   11 +----------
 net/tipc/link.c   |   12 ++++++++++++
 net/tipc/link.h   |    1 +
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a38c899..a3bdf5c 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -350,19 +350,10 @@ exit:
  */
 static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
 {
-	struct tipc_link *l_ptr;
-	struct tipc_link *temp_l_ptr;
-
 	read_lock_bh(&tipc_net_lock);
 	pr_info("Resetting bearer <%s>\n", b_ptr->name);
 	spin_lock_bh(&b_ptr->lock);
-	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
-		struct tipc_node *n_ptr = l_ptr->owner;
-
-		spin_lock_bh(&n_ptr->lock);
-		tipc_link_reset(l_ptr);
-		spin_unlock_bh(&n_ptr->lock);
-	}
+	tipc_link_reset_list(b_ptr);
 	spin_unlock_bh(&b_ptr->lock);
 	read_unlock_bh(&tipc_net_lock);
 	return 0;
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 17fbd15..3ff34e8 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -461,6 +461,18 @@ void tipc_link_reset(struct tipc_link *l_ptr)
 	link_reset_statistics(l_ptr);
 }
 
+void tipc_link_reset_list(struct tipc_bearer *b_ptr)
+{
+	struct tipc_link *l_ptr;
+
+	list_for_each_entry(l_ptr, &b_ptr->links, link_list) {
+		struct tipc_node *n_ptr = l_ptr->owner;
+
+		spin_lock_bh(&n_ptr->lock);
+		tipc_link_reset(l_ptr);
+		spin_unlock_bh(&n_ptr->lock);
+	}
+}
 
 static void link_activate(struct tipc_link *l_ptr)
 {
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 8addc5e..73beecb 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -231,6 +231,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area,
 struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
 					  int req_tlv_space);
 void tipc_link_reset(struct tipc_link *l_ptr);
+void tipc_link_reset_list(struct tipc_bearer *b_ptr);
 int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
 void tipc_link_send_names(struct list_head *message_list, u32 dest);
 int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf);
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 03/14] tipc: move code for deleting links from bearer.c to link.c
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

From: Ying Xue <ying.xue@windriver.com>

We break out the code for deleting attached links in the
function bearer_disable(), and define a new function named
tipc_link_delete_list() to do this job.

This commit incurs no functional changes, but makes the code of
function bearer_disable() cleaner. It is also a preparation
for a more important change to the bearer code, in a subsequent
commit in this series.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/bearer.c |    6 +-----
 net/tipc/link.c   |    9 +++++++++
 net/tipc/link.h   |    1 +
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a3bdf5c..a5be053 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -366,16 +366,12 @@ static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
  */
 static void bearer_disable(struct tipc_bearer *b_ptr)
 {
-	struct tipc_link *l_ptr;
-	struct tipc_link *temp_l_ptr;
 	struct tipc_link_req *temp_req;
 
 	pr_info("Disabling bearer <%s>\n", b_ptr->name);
 	spin_lock_bh(&b_ptr->lock);
 	b_ptr->media->disable_media(b_ptr);
-	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
-		tipc_link_delete(l_ptr);
-	}
+	tipc_link_delete_list(b_ptr);
 	temp_req = b_ptr->link_req;
 	b_ptr->link_req = NULL;
 	spin_unlock_bh(&b_ptr->lock);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 3ff34e8..424e9f3 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -313,6 +313,15 @@ void tipc_link_delete(struct tipc_link *l_ptr)
 	kfree(l_ptr);
 }
 
+void tipc_link_delete_list(struct tipc_bearer *b_ptr)
+{
+	struct tipc_link *l_ptr;
+	struct tipc_link *temp_l_ptr;
+
+	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
+		tipc_link_delete(l_ptr);
+	}
+}
 
 /**
  * link_schedule_port - schedule port for deferred sending
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 73beecb..994ebd1 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -219,6 +219,7 @@ void tipc_link_delete(struct tipc_link *l_ptr);
 void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
 void tipc_link_dup_send_queue(struct tipc_link *l_ptr,
 			      struct tipc_link *dest);
+void tipc_link_delete_list(struct tipc_bearer *b_ptr);
 void tipc_link_reset_fragments(struct tipc_link *l_ptr);
 int tipc_link_is_up(struct tipc_link *l_ptr);
 int tipc_link_is_active(struct tipc_link *l_ptr);
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 04/14] tipc: redefine 'started' flag in struct link to bitmap
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

From: Ying Xue <ying.xue@windriver.com>

Currently, the 'started' field in struct tipc_link represents only a
binary state, 'started' or 'not started'. We need it to represent
more link execution states in the coming commits in this series.
Hence, we rename the field to 'flags', and define the current
started/non-started state to be represented by the LSB bit of
that field.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c |    4 ++--
 net/tipc/link.h |   22 +++++++++++-----------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 424e9f3..2070d03 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -500,7 +500,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
 	struct tipc_link *other;
 	u32 cont_intv = l_ptr->continuity_interval;
 
-	if (!l_ptr->started && (event != STARTING_EVT))
+	if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
 		return;		/* Not yet. */
 
 	/* Check whether changeover is going on */
@@ -626,7 +626,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
 			link_set_timer(l_ptr, cont_intv);
 			break;
 		case STARTING_EVT:
-			l_ptr->started = 1;
+			l_ptr->flags |= LINK_STARTED;
 			/* fall through */
 		case TIMEOUT_EVT:
 			tipc_link_send_proto_msg(l_ptr, RESET_MSG, 0, 0, 0, 0, 0);
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 994ebd1..a900e74 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -1,7 +1,7 @@
 /*
  * net/tipc/link.h: Include file for TIPC link code
  *
- * Copyright (c) 1995-2006, Ericsson AB
+ * Copyright (c) 1995-2006, 2013, Ericsson AB
  * Copyright (c) 2004-2005, 2010-2011, Wind River Systems
  * All rights reserved.
  *
@@ -40,27 +40,27 @@
 #include "msg.h"
 #include "node.h"
 
-/*
- * Link reassembly status codes
+/* Link reassembly status codes
  */
 #define LINK_REASM_ERROR	-1
 #define LINK_REASM_COMPLETE	1
 
-/*
- * Out-of-range value for link sequence numbers
+/* Out-of-range value for link sequence numbers
  */
 #define INVALID_LINK_SEQ 0x10000
 
-/*
- * Link states
+/* Link working states
  */
 #define WORKING_WORKING 560810u
 #define WORKING_UNKNOWN 560811u
 #define RESET_UNKNOWN   560812u
 #define RESET_RESET     560813u
 
-/*
- * Starting value for maximum packet size negotiation on unicast links
+/* Link endpoint execution states
+ */
+#define LINK_STARTED    0x0001
+
+/* Starting value for maximum packet size negotiation on unicast links
  * (unless bearer MTU is less)
  */
 #define MAX_PKT_DEFAULT 1500
@@ -103,7 +103,7 @@ struct tipc_stats {
  * @timer: link timer
  * @owner: pointer to peer node
  * @link_list: adjacent links in bearer's list of links
- * @started: indicates if link has been started
+ * @flags: execution state flags for link endpoint instance
  * @checkpoint: reference point for triggering link continuity checking
  * @peer_session: link session # being used by peer end of link
  * @peer_bearer_id: bearer id used by link's peer endpoint
@@ -152,7 +152,7 @@ struct tipc_link {
 	struct list_head link_list;
 
 	/* Management and link supervision data */
-	int started;
+	unsigned int flags;
 	u32 checkpoint;
 	u32 peer_session;
 	u32 peer_bearer_id;
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 05/14] tipc: remove 'links' list from tipc_bearer struct
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

From: Ying Xue <ying.xue@windriver.com>

In our ongoing effort to simplify the TIPC locking structure,
we see a need to remove the linked list for tipc_links
in the bearer. This can be explained as follows.

Currently, we have three different ways to access a link,
via three different lists/tables:

1: Via a node hash table:
   Used by the time-critical outgoing/incoming data paths.
   (e.g. link_send_sections_fast() and tipc_recv_msg() ):

grab net_lock(read)
   find node from node hash table
   grab node_lock
       select link
       grab bearer_lock
          send_msg()
       release bearer_lock
   release node lock
release net_lock

2: Via a global linked list for nodes:
   Used by configuration commands (link_cmd_set_value())

grab net_lock(read)
   find node and link from global node list (using link name)
   grab node_lock
       update link
   release node lock
release net_lock

(Same locking order as above. No problem.)

3: Via the bearer's linked link list:
   Used by notifications from interface (e.g. tipc_disable_bearer() )

grab net_lock(write)
   grab bearer_lock
      get link ptr from bearer's link list
      get node from link
      grab node_lock
         delete link
      release node lock
   release bearer_lock
release net_lock

(Different order from above, but works because we grab the
outer net_lock in write mode first, excluding all other access.)

The first major goal in our simplification effort is to get rid
of the "big" net_lock, replacing it with rcu-locks when accessing
the node list and node hash array. This will come in a later patch
series.

But to get there we first need to rewrite access methods ##2 and 3,
since removal of net_lock would introduce three major problems:

a) In access method #2, we access the link before taking the
   protecting node_lock. This will not work once net_lock is gone,
   so we will have to change the access order. We will deal with
   this in a later commit in this series, "tipc: add node lock
   protection to link found by link_find_link()".

b) When the outer protection from net_lock is gone, taking
   bearer_lock and node_lock in opposite order of method 1) and 2)
   will become an obvious deadlock hazard. This is fixed in the
   commit ("tipc: remove bearer_lock from tipc_bearer struct")
   later in this series.

c) Similar to what is described in problem a), access method #3
   starts with using a link pointer that is unprotected by node_lock,
   in order to via that pointer find the correct node struct and
   lock it. Before we remove net_lock, this access order must be
   altered. This is what we do with this commit.

We can avoid introducing problem problem c) by even here using the
global node list to find the node, before accessing its links. When
we loop though the node list we use the own bearer identity as search
criteria, thus easily finding the links that are associated to the
resetting/disabling bearer. It should be noted that although this
method is somewhat slower than the current list traversal, it is in
no way time critical. This is only about resetting or deleting links,
something that must be considered relatively infrequent events.

As a bonus, we can get rid of the mutual pointers between links and
bearers. After this commit, pointer dependency go in one direction
only: from the link to the bearer.

This commit pre-empts introduction of problem c) as described above.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/bearer.c |    5 ++--
 net/tipc/bearer.h |    2 --
 net/tipc/core.c   |    2 +-
 net/tipc/link.c   |   68 +++++++++++++++++++----------------------------------
 net/tipc/link.h   |    8 +++----
 5 files changed, 30 insertions(+), 55 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index a5be053..4931eea 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -327,7 +327,6 @@ restart:
 	b_ptr->net_plane = bearer_id + 'A';
 	b_ptr->active = 1;
 	b_ptr->priority = priority;
-	INIT_LIST_HEAD(&b_ptr->links);
 	spin_lock_init(&b_ptr->lock);
 
 	res = tipc_disc_create(b_ptr, &b_ptr->bcast_addr, disc_domain);
@@ -353,7 +352,7 @@ static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
 	read_lock_bh(&tipc_net_lock);
 	pr_info("Resetting bearer <%s>\n", b_ptr->name);
 	spin_lock_bh(&b_ptr->lock);
-	tipc_link_reset_list(b_ptr);
+	tipc_link_reset_list(b_ptr->identity);
 	spin_unlock_bh(&b_ptr->lock);
 	read_unlock_bh(&tipc_net_lock);
 	return 0;
@@ -371,7 +370,7 @@ static void bearer_disable(struct tipc_bearer *b_ptr)
 	pr_info("Disabling bearer <%s>\n", b_ptr->name);
 	spin_lock_bh(&b_ptr->lock);
 	b_ptr->media->disable_media(b_ptr);
-	tipc_link_delete_list(b_ptr);
+	tipc_link_delete_list(b_ptr->identity);
 	temp_req = b_ptr->link_req;
 	b_ptr->link_req = NULL;
 	spin_unlock_bh(&b_ptr->lock);
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 4f5db9a..647cb1d 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -120,7 +120,6 @@ struct tipc_media {
  * @tolerance: default link tolerance for bearer
  * @identity: array index of this bearer within TIPC bearer array
  * @link_req: ptr to (optional) structure making periodic link setup requests
- * @links: list of non-congested links associated with bearer
  * @active: non-zero if bearer structure is represents a bearer
  * @net_plane: network plane ('A' through 'H') currently associated with bearer
  * @nodes: indicates which nodes in cluster can be reached through bearer
@@ -142,7 +141,6 @@ struct tipc_bearer {
 	u32 tolerance;
 	u32 identity;
 	struct tipc_link_req *link_req;
-	struct list_head links;
 	int active;
 	char net_plane;
 	struct tipc_node_map nodes;
diff --git a/net/tipc/core.c b/net/tipc/core.c
index f9e88d8..3f76b98 100644
--- a/net/tipc/core.c
+++ b/net/tipc/core.c
@@ -1,7 +1,7 @@
 /*
  * net/tipc/core.c: TIPC module code
  *
- * Copyright (c) 2003-2006, Ericsson AB
+ * Copyright (c) 2003-2006, 2013, Ericsson AB
  * Copyright (c) 2005-2006, 2010-2013, Wind River Systems
  * All rights reserved.
  *
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 2070d03..736b30c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -146,12 +146,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
 
 /**
  * link_timeout - handle expiration of link timer
- * @l_ptr: pointer to link
- *
- * This routine must not grab "tipc_net_lock" to avoid a potential deadlock conflict
- * with tipc_link_delete().  (There is no risk that the node will be deleted by
- * another thread because tipc_link_delete() always cancels the link timer before
- * tipc_node_delete() is called.)
  */
 static void link_timeout(struct tipc_link *l_ptr)
 {
@@ -213,8 +207,8 @@ static void link_set_timer(struct tipc_link *l_ptr, u32 time)
  * Returns pointer to link.
  */
 struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
-			      struct tipc_bearer *b_ptr,
-			      const struct tipc_media_addr *media_addr)
+				   struct tipc_bearer *b_ptr,
+				   const struct tipc_media_addr *media_addr)
 {
 	struct tipc_link *l_ptr;
 	struct tipc_msg *msg;
@@ -279,47 +273,32 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 
 	k_init_timer(&l_ptr->timer, (Handler)link_timeout,
 		     (unsigned long)l_ptr);
-	list_add_tail(&l_ptr->link_list, &b_ptr->links);
 
 	link_state_event(l_ptr, STARTING_EVT);
 
 	return l_ptr;
 }
 
-/**
- * tipc_link_delete - delete a link
- * @l_ptr: pointer to link
- *
- * Note: 'tipc_net_lock' is write_locked, bearer is locked.
- * This routine must not grab the node lock until after link timer cancellation
- * to avoid a potential deadlock situation.
- */
-void tipc_link_delete(struct tipc_link *l_ptr)
-{
-	if (!l_ptr) {
-		pr_err("Attempt to delete non-existent link\n");
-		return;
-	}
-
-	k_cancel_timer(&l_ptr->timer);
-
-	tipc_node_lock(l_ptr->owner);
-	tipc_link_reset(l_ptr);
-	tipc_node_detach_link(l_ptr->owner, l_ptr);
-	tipc_link_purge_queues(l_ptr);
-	list_del_init(&l_ptr->link_list);
-	tipc_node_unlock(l_ptr->owner);
-	k_term_timer(&l_ptr->timer);
-	kfree(l_ptr);
-}
 
-void tipc_link_delete_list(struct tipc_bearer *b_ptr)
+void tipc_link_delete_list(unsigned int bearer_id)
 {
 	struct tipc_link *l_ptr;
-	struct tipc_link *temp_l_ptr;
+	struct tipc_node *n_ptr;
+
+	list_for_each_entry(n_ptr, &tipc_node_list, list) {
+		spin_lock_bh(&n_ptr->lock);
+		l_ptr = n_ptr->links[bearer_id];
+		if (l_ptr) {
+			tipc_link_reset(l_ptr);
+			tipc_node_detach_link(n_ptr, l_ptr);
+			spin_unlock_bh(&n_ptr->lock);
 
-	list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
-		tipc_link_delete(l_ptr);
+			/* Nobody else can access this link now: */
+			del_timer_sync(&l_ptr->timer);
+			kfree(l_ptr);
+			continue;
+		}
+		spin_unlock_bh(&n_ptr->lock);
 	}
 }
 
@@ -470,15 +449,16 @@ void tipc_link_reset(struct tipc_link *l_ptr)
 	link_reset_statistics(l_ptr);
 }
 
-void tipc_link_reset_list(struct tipc_bearer *b_ptr)
+void tipc_link_reset_list(unsigned int bearer_id)
 {
 	struct tipc_link *l_ptr;
+	struct tipc_node *n_ptr;
 
-	list_for_each_entry(l_ptr, &b_ptr->links, link_list) {
-		struct tipc_node *n_ptr = l_ptr->owner;
-
+	list_for_each_entry(n_ptr, &tipc_node_list, list) {
 		spin_lock_bh(&n_ptr->lock);
-		tipc_link_reset(l_ptr);
+		l_ptr = n_ptr->links[bearer_id];
+		if (l_ptr)
+			tipc_link_reset(l_ptr);
 		spin_unlock_bh(&n_ptr->lock);
 	}
 }
diff --git a/net/tipc/link.h b/net/tipc/link.h
index a900e74..3340fc1 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -59,6 +59,7 @@
 /* Link endpoint execution states
  */
 #define LINK_STARTED    0x0001
+#define LINK_STOPPED    0x0002
 
 /* Starting value for maximum packet size negotiation on unicast links
  * (unless bearer MTU is less)
@@ -102,7 +103,6 @@ struct tipc_stats {
  * @media_addr: media address to use when sending messages over link
  * @timer: link timer
  * @owner: pointer to peer node
- * @link_list: adjacent links in bearer's list of links
  * @flags: execution state flags for link endpoint instance
  * @checkpoint: reference point for triggering link continuity checking
  * @peer_session: link session # being used by peer end of link
@@ -149,7 +149,6 @@ struct tipc_link {
 	struct tipc_media_addr media_addr;
 	struct timer_list timer;
 	struct tipc_node *owner;
-	struct list_head link_list;
 
 	/* Management and link supervision data */
 	unsigned int flags;
@@ -215,11 +214,10 @@ struct tipc_port;
 struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 			      struct tipc_bearer *b_ptr,
 			      const struct tipc_media_addr *media_addr);
-void tipc_link_delete(struct tipc_link *l_ptr);
+void tipc_link_delete_list(unsigned int bearer_id);
 void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
 void tipc_link_dup_send_queue(struct tipc_link *l_ptr,
 			      struct tipc_link *dest);
-void tipc_link_delete_list(struct tipc_bearer *b_ptr);
 void tipc_link_reset_fragments(struct tipc_link *l_ptr);
 int tipc_link_is_up(struct tipc_link *l_ptr);
 int tipc_link_is_active(struct tipc_link *l_ptr);
@@ -232,7 +230,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area,
 struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
 					  int req_tlv_space);
 void tipc_link_reset(struct tipc_link *l_ptr);
-void tipc_link_reset_list(struct tipc_bearer *b_ptr);
+void tipc_link_reset_list(unsigned int bearer_id);
 int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector);
 void tipc_link_send_names(struct list_head *message_list, u32 dest);
 int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf);
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 06/14] tipc: change reception of tunnelled duplicate packets
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

When a second link to a destination comes up, some sender sockets will
steer their subsequent traffic through the new link. In order to
guarantee preserved packet order and cardinality for those sockets, we
tunnel a duplicate of the old link's send queue through the new link
before we open it for regular traffic. The last arriving packet copy,
on whichever link, will be dropped at the receiving end based on the
original sequence number, to ensure that only one copy is delivered to
the end receiver.

In this commit, we change the algorithm for receiving DUPLICATE_MSG
packets, at the same time delegating it to a new subfunction,
tipc_link_dup_rcv(). Instead of returning an extracted inner packet to
the packet reception loop in tipc_rcv(), we just add it to the receiving
(new) link's deferred packet queue. The packet will then be processed by
that link when it receives its first non-tunneled packet, i.e., at
latest when the changeover procedure is finished.

Because tipc_link_tunnel_rcv()/tipc_link_dup_rcv() now is consuming all
packets of type DUPLICATE_MSG, the calling tipc_rcv() function can omit
testing for this. This in turn means that the current conditional jump
to the label 'protocol_check' becomes redundant, and we can remove that
label.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/link.c |   53 ++++++++++++++++++++++++++++++++---------------------
 1 file changed, 32 insertions(+), 21 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 736b30c..80f9eb2 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1436,7 +1436,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		u32 seq_no;
 		u32 ackd;
 		u32 released = 0;
-		int type;
 
 		head = head->next;
 		buf->next = NULL;
@@ -1524,7 +1523,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		}
 
 		/* Now (finally!) process the incoming message */
-protocol_check:
 		if (unlikely(!link_working_working(l_ptr))) {
 			if (msg_user(msg) == LINK_PROTOCOL) {
 				link_recv_proto_msg(l_ptr, buf);
@@ -1598,15 +1596,11 @@ deliver:
 			tipc_node_unlock(n_ptr);
 			continue;
 		case CHANGEOVER_PROTOCOL:
-			type = msg_type(msg);
-			if (tipc_link_tunnel_rcv(&l_ptr, &buf)) {
-				msg = buf_msg(buf);
-				seq_no = msg_seqno(msg);
-				if (type == ORIGINAL_MSG)
-					goto deliver;
-				goto protocol_check;
-			}
-			break;
+			if (!tipc_link_tunnel_rcv(&l_ptr, &buf))
+				break;
+			msg = buf_msg(buf);
+			seq_no = msg_seqno(msg);
+			goto deliver;
 		default:
 			kfree_skb(buf);
 			buf = NULL;
@@ -2106,7 +2100,30 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
 	return eb;
 }
 
-/*  tipc_link_tunnel_rcv(): Receive a tunneled packet, sent
+
+
+/* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet.
+ * Owner node is locked.
+ */
+static void tipc_link_dup_rcv(struct tipc_link *l_ptr,
+			      struct sk_buff *t_buf)
+{
+	struct sk_buff *buf;
+
+	if (!tipc_link_is_up(l_ptr))
+		return;
+
+	buf = buf_extract(t_buf, INT_H_SIZE);
+	if (buf == NULL) {
+		pr_warn("%sfailed to extract inner dup pkt\n", link_co_err);
+		return;
+	}
+
+	/* Add buffer to deferred queue, if applicable: */
+	link_handle_out_of_seq_msg(l_ptr, buf);
+}
+
+/*  tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent
  *  via other link as result of a failover (ORIGINAL_MSG) or
  *  a new active link (DUPLICATE_MSG). Failover packets are
  *  returned to the active link for delivery upwards.
@@ -2125,6 +2142,7 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
 
 	if (bearer_id >= MAX_BEARERS)
 		goto exit;
+
 	dest_link = (*l_ptr)->owner->links[bearer_id];
 	if (!dest_link)
 		goto exit;
@@ -2137,15 +2155,8 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
 	msg = msg_get_wrapped(tunnel_msg);
 
 	if (msg_typ == DUPLICATE_MSG) {
-		if (less(msg_seqno(msg), mod(dest_link->next_in_no)))
-			goto exit;
-		*buf = buf_extract(tunnel_buf, INT_H_SIZE);
-		if (*buf == NULL) {
-			pr_warn("%sduplicate msg dropped\n", link_co_err);
-			goto exit;
-		}
-		kfree_skb(tunnel_buf);
-		return 1;
+		tipc_link_dup_rcv(dest_link, tunnel_buf);
+		goto exit;
 	}
 
 	/* First original message ?: */
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 07/14] tipc: change reception of tunnelled failover packets
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

When a link is reset, and there is a redundant link available, all
sender sockets will steer their subsequent traffic through the
remaining link. In order to guarantee preserved packet order and
cardinality during the transition, we tunnel the failing link's send
queue through the remaining link before we allow any sockets to use it.

In this commit, we change the algorithm for receiving failover
("ORIGINAL_MSG") packets in tipc_link_tunnel_rcv(), at the same time
delegating it to a new subfuncton, tipc_link_failover_rcv(). Instead
of directly returning an extracted inner packet to the packet reception
loop in tipc_rcv(), we first check if it is a message fragment, in which
case we append it to the reset link's fragment chain. If the fragment
chain is complete, we return the whole chain instead of the individual
buffer, eliminating any need for the tipc_rcv() loop to do reassembly of
tunneled packets.

This change makes it possible to further simplify tipc_link_tunnel_rcv(),
as well as the calling tipc_rcv() loop. We will do that in later
commits. It also makes it possible to identify a single spot in the code
where we can tell that a failover procedure is finished, something that
is useful when we are deleting links after a failover. This will also
be done in a later commit.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/link.c |   75 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 47 insertions(+), 28 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 80f9eb2..978fd3a 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2123,6 +2123,50 @@ static void tipc_link_dup_rcv(struct tipc_link *l_ptr,
 	link_handle_out_of_seq_msg(l_ptr, buf);
 }
 
+/*  tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet
+ *  Owner node is locked.
+ */
+static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
+					      struct sk_buff *t_buf)
+{
+	struct tipc_msg *t_msg = buf_msg(t_buf);
+	struct sk_buff *buf = NULL;
+	struct tipc_msg *msg;
+
+	if (tipc_link_is_up(l_ptr))
+		tipc_link_reset(l_ptr);
+
+	/* First failover packet? */
+	if (l_ptr->exp_msg_count == START_CHANGEOVER)
+		l_ptr->exp_msg_count = msg_msgcnt(t_msg);
+
+	/* Should there be an inner packet? */
+	if (l_ptr->exp_msg_count) {
+		l_ptr->exp_msg_count--;
+		buf = buf_extract(t_buf, INT_H_SIZE);
+		if (buf == NULL) {
+			pr_warn("%sno inner failover pkt\n", link_co_err);
+			goto exit;
+		}
+		msg = buf_msg(buf);
+
+		if (less(msg_seqno(msg), l_ptr->reset_checkpoint)) {
+			kfree_skb(buf);
+			buf = NULL;
+			goto exit;
+		}
+		if (msg_user(msg) == MSG_FRAGMENTER) {
+			l_ptr->stats.recv_fragments++;
+			tipc_link_frag_rcv(&l_ptr->reasm_head,
+					   &l_ptr->reasm_tail,
+					   &buf);
+		}
+	}
+
+exit:
+	return buf;
+}
+
 /*  tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent
  *  via other link as result of a failover (ORIGINAL_MSG) or
  *  a new active link (DUPLICATE_MSG). Failover packets are
@@ -2134,10 +2178,8 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
 {
 	struct sk_buff *tunnel_buf = *buf;
 	struct tipc_link *dest_link;
-	struct tipc_msg *msg;
 	struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf);
 	u32 msg_typ = msg_type(tunnel_msg);
-	u32 msg_count = msg_msgcnt(tunnel_msg);
 	u32 bearer_id = msg_bearer_id(tunnel_msg);
 
 	if (bearer_id >= MAX_BEARERS)
@@ -2152,42 +2194,19 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
 		goto exit;
 	}
 	*l_ptr = dest_link;
-	msg = msg_get_wrapped(tunnel_msg);
 
 	if (msg_typ == DUPLICATE_MSG) {
 		tipc_link_dup_rcv(dest_link, tunnel_buf);
 		goto exit;
 	}
 
-	/* First original message ?: */
-	if (tipc_link_is_up(dest_link)) {
-		pr_info("%s<%s>, changeover initiated by peer\n", link_rst_msg,
-			dest_link->name);
-		tipc_link_reset(dest_link);
-		dest_link->exp_msg_count = msg_count;
-		if (!msg_count)
-			goto exit;
-	} else if (dest_link->exp_msg_count == START_CHANGEOVER) {
-		dest_link->exp_msg_count = msg_count;
-		if (!msg_count)
-			goto exit;
-	}
+	if (msg_type(tunnel_msg) == ORIGINAL_MSG) {
+		*buf = tipc_link_failover_rcv(dest_link, tunnel_buf);
 
-	/* Receive original message */
-	if (dest_link->exp_msg_count == 0) {
-		pr_warn("%sgot too many tunnelled messages\n", link_co_err);
-		goto exit;
-	}
-	dest_link->exp_msg_count--;
-	if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
-		goto exit;
-	} else {
-		*buf = buf_extract(tunnel_buf, INT_H_SIZE);
+		/* Do we have a buffer/buffer chain to return? */
 		if (*buf != NULL) {
 			kfree_skb(tunnel_buf);
 			return 1;
-		} else {
-			pr_warn("%soriginal msg dropped\n", link_co_err);
 		}
 	}
 exit:
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 08/14] tipc: change signature of tunnelling reception function
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

After the earlier commits in this series related to the function
tipc_link_tunnel_rcv(), we can now go further and simplify its
signature.

The function now consumes all DUPLICATE packets, and only returns such
ORIGINAL packets that are ready for immediate delivery, i.e., no
more link level protocol processing needs to be done by the caller.
As a consequence, the the caller, tipc_rcv(), does not access the link
pointer after call return, and it becomes unnecessary to pass a link
pointer reference in the call. Instead, we now only pass it the tunnel
link's owner node, which is sufficient to find the destination link for
the tunnelled packet.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/link.c |   14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 978fd3a..76adca6 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -78,7 +78,7 @@ static const char *link_unk_evt = "Unknown link event ";
 static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
 				       struct sk_buff *buf);
 static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
-static int  tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
+static int  tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 				 struct sk_buff **buf);
 static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
 static int  link_send_sections_long(struct tipc_port *sender,
@@ -1596,7 +1596,7 @@ deliver:
 			tipc_node_unlock(n_ptr);
 			continue;
 		case CHANGEOVER_PROTOCOL:
-			if (!tipc_link_tunnel_rcv(&l_ptr, &buf))
+			if (!tipc_link_tunnel_rcv(n_ptr, &buf))
 				break;
 			msg = buf_msg(buf);
 			seq_no = msg_seqno(msg);
@@ -2173,7 +2173,7 @@ exit:
  *  returned to the active link for delivery upwards.
  *  Owner node is locked.
  */
-static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
+static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 				struct sk_buff **buf)
 {
 	struct sk_buff *tunnel_buf = *buf;
@@ -2185,15 +2185,9 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
 	if (bearer_id >= MAX_BEARERS)
 		goto exit;
 
-	dest_link = (*l_ptr)->owner->links[bearer_id];
+	dest_link = n_ptr->links[bearer_id];
 	if (!dest_link)
 		goto exit;
-	if (dest_link == *l_ptr) {
-		pr_err("Unexpected changeover message on link <%s>\n",
-		       (*l_ptr)->name);
-		goto exit;
-	}
-	*l_ptr = dest_link;
 
 	if (msg_typ == DUPLICATE_MSG) {
 		tipc_link_dup_rcv(dest_link, tunnel_buf);
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 09/14] tipc: more cleanup of tunnelling reception function
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

We simplify and slim down the code in function tipc_tunnel_rcv()
No impact on the users of this function.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c |   21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 76adca6..00f529e 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2179,9 +2179,10 @@ static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 	struct sk_buff *tunnel_buf = *buf;
 	struct tipc_link *dest_link;
 	struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf);
-	u32 msg_typ = msg_type(tunnel_msg);
 	u32 bearer_id = msg_bearer_id(tunnel_msg);
 
+	*buf = NULL;
+
 	if (bearer_id >= MAX_BEARERS)
 		goto exit;
 
@@ -2189,24 +2190,16 @@ static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 	if (!dest_link)
 		goto exit;
 
-	if (msg_typ == DUPLICATE_MSG) {
+	if (msg_type(tunnel_msg) == DUPLICATE_MSG)
 		tipc_link_dup_rcv(dest_link, tunnel_buf);
-		goto exit;
-	}
-
-	if (msg_type(tunnel_msg) == ORIGINAL_MSG) {
+	else if (msg_type(tunnel_msg) == ORIGINAL_MSG)
 		*buf = tipc_link_failover_rcv(dest_link, tunnel_buf);
+	else
+		pr_warn("%sunknown tunnel pkt received\n", link_co_err);
 
-		/* Do we have a buffer/buffer chain to return? */
-		if (*buf != NULL) {
-			kfree_skb(tunnel_buf);
-			return 1;
-		}
-	}
 exit:
-	*buf = NULL;
 	kfree_skb(tunnel_buf);
-	return 0;
+	return *buf != NULL;
 }
 
 /*
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 10/14] tipc: rename stack variables in function tipc_link_tunnel_rcv
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

After the previous redesign of the tunnel reception algorithm and
functions, we finalize it by renaming a couple of stack variables
in tipc_tunnel_rcv(). This makes it more consistent with the naming
scheme elsewhere in this part of the code.

This change is purely cosmetic, with no functional changes.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/link.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 00f529e..758f7cd 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2176,29 +2176,29 @@ exit:
 static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 				struct sk_buff **buf)
 {
-	struct sk_buff *tunnel_buf = *buf;
-	struct tipc_link *dest_link;
-	struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf);
-	u32 bearer_id = msg_bearer_id(tunnel_msg);
+	struct sk_buff *t_buf = *buf;
+	struct tipc_link *l_ptr;
+	struct tipc_msg *t_msg = buf_msg(t_buf);
+	u32 bearer_id = msg_bearer_id(t_msg);
 
 	*buf = NULL;
 
 	if (bearer_id >= MAX_BEARERS)
 		goto exit;
 
-	dest_link = n_ptr->links[bearer_id];
-	if (!dest_link)
+	l_ptr = n_ptr->links[bearer_id];
+	if (!l_ptr)
 		goto exit;
 
-	if (msg_type(tunnel_msg) == DUPLICATE_MSG)
-		tipc_link_dup_rcv(dest_link, tunnel_buf);
-	else if (msg_type(tunnel_msg) == ORIGINAL_MSG)
-		*buf = tipc_link_failover_rcv(dest_link, tunnel_buf);
+	if (msg_type(t_msg) == DUPLICATE_MSG)
+		tipc_link_dup_rcv(l_ptr, t_buf);
+	else if (msg_type(t_msg) == ORIGINAL_MSG)
+		*buf = tipc_link_failover_rcv(l_ptr, t_buf);
 	else
 		pr_warn("%sunknown tunnel pkt received\n", link_co_err);
 
 exit:
-	kfree_skb(tunnel_buf);
+	kfree_skb(t_buf);
 	return *buf != NULL;
 }
 
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 11/14] tipc: changes to general packet reception algorithm
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

We change the order of checking for destination users when processing
incoming packets. By placing the checks for users that may potentially
replace the processed buffer, i.e., CHANGEOVER_PROTOCOL and
MSG_FRAGMENTER, in a separate step before we check for the true end
users, we get rid of a label and a 'goto', at the same time making the
code more comprehensible and easy to follow.

This commit does not change any functionality, it is just a cosmetic
code reshuffle.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/link.c |   76 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 36 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index 758f7cd..1228d6c 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1483,7 +1483,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
 			msg_user(msg) == LINK_PROTOCOL &&
 			(msg_type(msg) == RESET_MSG ||
-					msg_type(msg) == ACTIVATE_MSG) &&
+			 msg_type(msg) == ACTIVATE_MSG) &&
 			!msg_redundant_link(msg))
 			n_ptr->block_setup &= ~WAIT_PEER_DOWN;
 
@@ -1502,7 +1502,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		while ((crs != l_ptr->next_out) &&
 		       less_eq(buf_seqno(crs), ackd)) {
 			struct sk_buff *next = crs->next;
-
 			kfree_skb(crs);
 			crs = next;
 			released++;
@@ -1515,14 +1514,17 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		/* Try sending any messages link endpoint has pending */
 		if (unlikely(l_ptr->next_out))
 			tipc_link_push_queue(l_ptr);
+
 		if (unlikely(!list_empty(&l_ptr->waiting_ports)))
 			tipc_link_wakeup_ports(l_ptr, 0);
+
 		if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
 			l_ptr->stats.sent_acks++;
-			tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
+			tipc_link_send_proto_msg(l_ptr, STATE_MSG,
+						 0, 0, 0, 0, 0);
 		}
 
-		/* Now (finally!) process the incoming message */
+		/* Process the incoming packet */
 		if (unlikely(!link_working_working(l_ptr))) {
 			if (msg_user(msg) == LINK_PROTOCOL) {
 				link_recv_proto_msg(l_ptr, buf);
@@ -1554,14 +1556,40 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
 		l_ptr->next_in_no++;
 		if (unlikely(l_ptr->oldest_deferred_in))
 			head = link_insert_deferred_queue(l_ptr, head);
-deliver:
-		if (likely(msg_isdata(msg))) {
+
+		/* Deliver packet/message to correct user: */
+		if (unlikely(msg_user(msg) ==  CHANGEOVER_PROTOCOL)) {
+			if (!tipc_link_tunnel_rcv(n_ptr, &buf)) {
+				tipc_node_unlock(n_ptr);
+				continue;
+			}
+			msg = buf_msg(buf);
+		} else if (msg_user(msg) == MSG_FRAGMENTER) {
+			int rc;
+
+			l_ptr->stats.recv_fragments++;
+			rc = tipc_link_frag_rcv(&l_ptr->reasm_head,
+						&l_ptr->reasm_tail,
+						&buf);
+			if (rc == LINK_REASM_COMPLETE) {
+				l_ptr->stats.recv_fragmented++;
+				msg = buf_msg(buf);
+			} else {
+				if (rc == LINK_REASM_ERROR)
+					tipc_link_reset(l_ptr);
+				tipc_node_unlock(n_ptr);
+				continue;
+			}
+		}
+
+		switch (msg_user(msg)) {
+		case TIPC_LOW_IMPORTANCE:
+		case TIPC_MEDIUM_IMPORTANCE:
+		case TIPC_HIGH_IMPORTANCE:
+		case TIPC_CRITICAL_IMPORTANCE:
 			tipc_node_unlock(n_ptr);
 			tipc_port_recv_msg(buf);
 			continue;
-		}
-		switch (msg_user(msg)) {
-			int ret;
 		case MSG_BUNDLER:
 			l_ptr->stats.recv_bundles++;
 			l_ptr->stats.recv_bundled += msg_msgcnt(msg);
@@ -1573,44 +1601,20 @@ deliver:
 			tipc_node_unlock(n_ptr);
 			tipc_named_recv(buf);
 			continue;
-		case BCAST_PROTOCOL:
-			tipc_link_recv_sync(n_ptr, buf);
-			tipc_node_unlock(n_ptr);
-			continue;
 		case CONN_MANAGER:
 			tipc_node_unlock(n_ptr);
 			tipc_port_recv_proto_msg(buf);
 			continue;
-		case MSG_FRAGMENTER:
-			l_ptr->stats.recv_fragments++;
-			ret = tipc_link_frag_rcv(&l_ptr->reasm_head,
-						 &l_ptr->reasm_tail,
-						 &buf);
-			if (ret == LINK_REASM_COMPLETE) {
-				l_ptr->stats.recv_fragmented++;
-				msg = buf_msg(buf);
-				goto deliver;
-			}
-			if (ret == LINK_REASM_ERROR)
-				tipc_link_reset(l_ptr);
-			tipc_node_unlock(n_ptr);
-			continue;
-		case CHANGEOVER_PROTOCOL:
-			if (!tipc_link_tunnel_rcv(n_ptr, &buf))
-				break;
-			msg = buf_msg(buf);
-			seq_no = msg_seqno(msg);
-			goto deliver;
+		case BCAST_PROTOCOL:
+			tipc_link_recv_sync(n_ptr, buf);
+			break;
 		default:
 			kfree_skb(buf);
-			buf = NULL;
 			break;
 		}
 		tipc_node_unlock(n_ptr);
-		tipc_net_route_msg(buf);
 		continue;
 unlock_discard:
-
 		tipc_node_unlock(n_ptr);
 discard:
 		kfree_skb(buf);
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 12/14] tipc: delay delete of link when failover is needed
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

When a bearer is disabled, all its attached links are deleted.
Ideally, we should do link failover to redundant links on other bearers,
if there are any, in such cases. This would be consistent with current
behavior when a link is reset, but not deleted. However, due to the
complexity involved, and the (wrongly) perceived low demand for this
feature, it was never implemented until now.

We mark the doomed link for deletion with a new flag, but wait until the
failover process is finished before we actually delete it. With the
improved link tunnelling/failover code introduced earlier in this commit
series, it is now easy to identify a spot in the code where the failover
is finished and it is safe to delete the marked link. Moreover, the test
for the flag and the deletion can be done synchronously, and outside the
most time critical data path.

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/bearer.c |   12 ++++++------
 net/tipc/link.c   |   31 ++++++++++++++++++++++---------
 net/tipc/link.h   |    2 +-
 net/tipc/node.c   |    8 +++++++-
 4 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 4931eea..60caa45 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -51,7 +51,7 @@ static struct tipc_media * const media_info_array[] = {
 
 struct tipc_bearer tipc_bearers[MAX_BEARERS];
 
-static void bearer_disable(struct tipc_bearer *b_ptr);
+static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
 
 /**
  * tipc_media_find - locates specified media object by name
@@ -331,7 +331,7 @@ restart:
 
 	res = tipc_disc_create(b_ptr, &b_ptr->bcast_addr, disc_domain);
 	if (res) {
-		bearer_disable(b_ptr);
+		bearer_disable(b_ptr, false);
 		pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
 			name);
 		goto exit;
@@ -363,14 +363,14 @@ static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
  *
  * Note: This routine assumes caller holds tipc_net_lock.
  */
-static void bearer_disable(struct tipc_bearer *b_ptr)
+static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
 {
 	struct tipc_link_req *temp_req;
 
 	pr_info("Disabling bearer <%s>\n", b_ptr->name);
 	spin_lock_bh(&b_ptr->lock);
 	b_ptr->media->disable_media(b_ptr);
-	tipc_link_delete_list(b_ptr->identity);
+	tipc_link_delete_list(b_ptr->identity, shutting_down);
 	temp_req = b_ptr->link_req;
 	b_ptr->link_req = NULL;
 	spin_unlock_bh(&b_ptr->lock);
@@ -392,7 +392,7 @@ int tipc_disable_bearer(const char *name)
 		pr_warn("Attempt to disable unknown bearer <%s>\n", name);
 		res = -EINVAL;
 	} else {
-		bearer_disable(b_ptr);
+		bearer_disable(b_ptr, false);
 		res = 0;
 	}
 	write_unlock_bh(&tipc_net_lock);
@@ -612,6 +612,6 @@ void tipc_bearer_stop(void)
 
 	for (i = 0; i < MAX_BEARERS; i++) {
 		if (tipc_bearers[i].active)
-			bearer_disable(&tipc_bearers[i]);
+			bearer_disable(&tipc_bearers[i], true);
 	}
 }
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 1228d6c..a13b90d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -280,7 +280,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 }
 
 
-void tipc_link_delete_list(unsigned int bearer_id)
+void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down)
 {
 	struct tipc_link *l_ptr;
 	struct tipc_node *n_ptr;
@@ -290,12 +290,20 @@ void tipc_link_delete_list(unsigned int bearer_id)
 		l_ptr = n_ptr->links[bearer_id];
 		if (l_ptr) {
 			tipc_link_reset(l_ptr);
-			tipc_node_detach_link(n_ptr, l_ptr);
-			spin_unlock_bh(&n_ptr->lock);
-
-			/* Nobody else can access this link now: */
-			del_timer_sync(&l_ptr->timer);
-			kfree(l_ptr);
+			if (shutting_down || !tipc_node_is_up(n_ptr)) {
+				tipc_node_detach_link(l_ptr->owner, l_ptr);
+				tipc_link_reset_fragments(l_ptr);
+				spin_unlock_bh(&n_ptr->lock);
+
+				/* Nobody else can access this link now: */
+				del_timer_sync(&l_ptr->timer);
+				kfree(l_ptr);
+			} else {
+				/* Detach/delete when failover is finished: */
+				l_ptr->flags |= LINK_STOPPED;
+				spin_unlock_bh(&n_ptr->lock);
+				del_timer_sync(&l_ptr->timer);
+			}
 			continue;
 		}
 		spin_unlock_bh(&n_ptr->lock);
@@ -480,6 +488,9 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
 	struct tipc_link *other;
 	u32 cont_intv = l_ptr->continuity_interval;
 
+	if (l_ptr->flags & LINK_STOPPED)
+		return;
+
 	if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
 		return;		/* Not yet. */
 
@@ -2166,8 +2177,11 @@ static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
 					   &buf);
 		}
 	}
-
 exit:
+	if ((l_ptr->exp_msg_count == 0) && (l_ptr->flags & LINK_STOPPED)) {
+		tipc_node_detach_link(l_ptr->owner, l_ptr);
+		kfree(l_ptr);
+	}
 	return buf;
 }
 
@@ -2200,7 +2214,6 @@ static int tipc_link_tunnel_rcv(struct tipc_node *n_ptr,
 		*buf = tipc_link_failover_rcv(l_ptr, t_buf);
 	else
 		pr_warn("%sunknown tunnel pkt received\n", link_co_err);
-
 exit:
 	kfree_skb(t_buf);
 	return *buf != NULL;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 3340fc1..45b9cd0 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -214,7 +214,7 @@ struct tipc_port;
 struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
 			      struct tipc_bearer *b_ptr,
 			      const struct tipc_media_addr *media_addr);
-void tipc_link_delete_list(unsigned int bearer_id);
+void tipc_link_delete_list(unsigned int bearer_id, bool shutting_down);
 void tipc_link_failover_send_queue(struct tipc_link *l_ptr);
 void tipc_link_dup_send_queue(struct tipc_link *l_ptr,
 			      struct tipc_link *dest);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index efe4d41..833324b 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -249,7 +249,13 @@ void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 
 void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
 {
-	n_ptr->links[l_ptr->b_ptr->identity] = NULL;
+	int i;
+
+	for (i = 0; i < MAX_BEARERS; i++) {
+		if (l_ptr == n_ptr->links[i])
+			break;
+	}
+	n_ptr->links[i] = NULL;
 	atomic_dec(&tipc_num_links);
 	n_ptr->link_cnt--;
 }
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* [PATCH net-next 13/14] tipc: remove bearer_lock from tipc_bearer struct
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

From: Ying Xue <ying.xue@windriver.com>

After the earlier commits ("tipc: remove 'links' list from
tipc_bearer struct") and ("tipc: introduce new spinlock to protect
struct link_req"), there is no longer any need to protect struct
link_req or or any link list by use of bearer_lock. Furthermore,
we have eliminated the need for using bearer_lock during downcalls
(send) from the link to the bearer, since we have ensured that
bearers always have a longer life cycle that their associated links,
and always contain valid data.

So, the only need now for a lock protecting bearers is for guaranteeing
consistency of the bearer list itself. For this, it is sufficient, at
least for the time being, to continue applying 'net_lock´ in write mode.

By removing bearer_lock we also pre-empt introduction of issue b) descibed
in the previous commit "tipc: remove 'links' list from tipc_bearer struct":

"b) When the outer protection from net_lock is gone, taking
    bearer_lock and node_lock in opposite order of method 1) and 2)
    will become an obvious deadlock hazard".

Therefore, we now eliminate the bearer_lock spinlock.

Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
 net/tipc/bcast.c  |    1 -
 net/tipc/bearer.c |   16 +++-------------
 net/tipc/bearer.h |    5 +----
 3 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index af35f76..06a639c 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -785,7 +785,6 @@ void tipc_bclink_init(void)
 	bcl->owner = &bclink->node;
 	bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
 	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
-	spin_lock_init(&bcbearer->bearer.lock);
 	bcl->b_ptr = &bcbearer->bearer;
 	bcl->state = WORKING_WORKING;
 	strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 60caa45..242cddd 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -327,7 +327,6 @@ restart:
 	b_ptr->net_plane = bearer_id + 'A';
 	b_ptr->active = 1;
 	b_ptr->priority = priority;
-	spin_lock_init(&b_ptr->lock);
 
 	res = tipc_disc_create(b_ptr, &b_ptr->bcast_addr, disc_domain);
 	if (res) {
@@ -351,9 +350,7 @@ static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
 {
 	read_lock_bh(&tipc_net_lock);
 	pr_info("Resetting bearer <%s>\n", b_ptr->name);
-	spin_lock_bh(&b_ptr->lock);
 	tipc_link_reset_list(b_ptr->identity);
-	spin_unlock_bh(&b_ptr->lock);
 	read_unlock_bh(&tipc_net_lock);
 	return 0;
 }
@@ -365,19 +362,12 @@ static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
  */
 static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
 {
-	struct tipc_link_req *temp_req;
-
 	pr_info("Disabling bearer <%s>\n", b_ptr->name);
-	spin_lock_bh(&b_ptr->lock);
 	b_ptr->media->disable_media(b_ptr);
-	tipc_link_delete_list(b_ptr->identity, shutting_down);
-	temp_req = b_ptr->link_req;
-	b_ptr->link_req = NULL;
-	spin_unlock_bh(&b_ptr->lock);
-
-	if (temp_req)
-		tipc_disc_delete(temp_req);
 
+	tipc_link_delete_list(b_ptr->identity, shutting_down);
+	if (b_ptr->link_req)
+		tipc_disc_delete(b_ptr->link_req);
 	memset(b_ptr, 0, sizeof(struct tipc_bearer));
 }
 
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 647cb1d..425dd81 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -107,10 +107,8 @@ struct tipc_media {
 
 /**
  * struct tipc_bearer - Generic TIPC bearer structure
- * @dev: ptr to associated network device
- * @usr_handle: pointer to additional media-specific information about bearer
+ * @media_ptr: pointer to additional media-specific information about bearer
  * @mtu: max packet size bearer can support
- * @lock: spinlock for controlling access to bearer
  * @addr: media-specific address associated with bearer
  * @name: bearer name (format = media:interface)
  * @media: ptr to media structure associated with bearer
@@ -133,7 +131,6 @@ struct tipc_bearer {
 	u32 mtu;				/* initalized by media */
 	struct tipc_media_addr addr;		/* initalized by media */
 	char name[TIPC_MAX_BEARER_NAME];
-	spinlock_t lock;
 	struct tipc_media *media;
 	struct tipc_media_addr bcast_addr;
 	u32 priority;
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
tipc-discussion mailing list
tipc-discussion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

^ permalink raw reply related

* [PATCH net-next 14/14] tipc: add node_lock protection to link lookup function
From: Jon Maloy @ 2014-02-12 18:31 UTC (permalink / raw)
  To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1392229874-29675-1-git-send-email-jon.maloy@ericsson.com>

In an earlier commit, ("tipc: remove links list from bearer struct")
we described three issues that need to be pre-emptively resolved before
we can remove tipc_net_lock. Here we resolve issue a) described in that
commit:

"a) In access method #2, we access the link before taking the
    protecting node_lock. This will not work once net_lock is gone,
    so we will have to change the access order. We will deal with
    this in a later commit in this series."

Here, we change that access order, by ensuring that the function
link_find_link() returns only a safe reference for finding
the link, i.e., a node pointer and an index into its 'links' array,
not the link pointer itself. We also change all callers of this
function to first take the node lock before they can check if there
still is a valid link pointer at the returned index. Since the
function now returns a node pointer rather than a link pointer,
we rename it to the more appropriate 'tipc_link_find_owner().

Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
---
 net/tipc/link.c |  110 ++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 65 insertions(+), 45 deletions(-)

diff --git a/net/tipc/link.c b/net/tipc/link.c
index a13b90d..11f2222 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2389,35 +2389,40 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
 	l_ptr->queue_limit[MSG_FRAGMENTER] = 4000;
 }
 
-/**
- * link_find_link - locate link by name
- * @name: ptr to link name string
- * @node: ptr to area to be filled with ptr to associated node
- *
+/* tipc_link_find_owner - locate owner node of link by link's name
+ * @name: pointer to link name string
+ * @bearer_id: pointer to index in 'node->links' array where the link was found.
  * Caller must hold 'tipc_net_lock' to ensure node and bearer are not deleted;
  * this also prevents link deletion.
  *
- * Returns pointer to link (or 0 if invalid link name).
+ * Returns pointer to node owning the link, or 0 if no matching link is found.
  */
-static struct tipc_link *link_find_link(const char *name,
-					struct tipc_node **node)
+static struct tipc_node *tipc_link_find_owner(const char *link_name,
+					      unsigned int *bearer_id)
 {
 	struct tipc_link *l_ptr;
 	struct tipc_node *n_ptr;
+	struct tipc_node *tmp_n_ptr;
+	struct tipc_node *found_node = 0;
+
 	int i;
 
-	list_for_each_entry(n_ptr, &tipc_node_list, list) {
+	*bearer_id = 0;
+	list_for_each_entry_safe(n_ptr, tmp_n_ptr, &tipc_node_list, list) {
+		spin_lock(&n_ptr->lock);
 		for (i = 0; i < MAX_BEARERS; i++) {
 			l_ptr = n_ptr->links[i];
-			if (l_ptr && !strcmp(l_ptr->name, name))
-				goto found;
+			if (l_ptr && !strcmp(l_ptr->name, link_name)) {
+				*bearer_id = i;
+				found_node = n_ptr;
+				break;
+			}
 		}
+		spin_unlock(&n_ptr->lock);
+		if (found_node)
+			break;
 	}
-	l_ptr = NULL;
-	n_ptr = NULL;
-found:
-	*node = n_ptr;
-	return l_ptr;
+	return found_node;
 }
 
 /**
@@ -2459,32 +2464,33 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
 	struct tipc_link *l_ptr;
 	struct tipc_bearer *b_ptr;
 	struct tipc_media *m_ptr;
+	int bearer_id;
 	int res = 0;
 
-	l_ptr = link_find_link(name, &node);
-	if (l_ptr) {
-		/*
-		 * acquire node lock for tipc_link_send_proto_msg().
-		 * see "TIPC locking policy" in net.c.
-		 */
+	node = tipc_link_find_owner(name, &bearer_id);
+	if (node) {
 		tipc_node_lock(node);
-		switch (cmd) {
-		case TIPC_CMD_SET_LINK_TOL:
-			link_set_supervision_props(l_ptr, new_value);
-			tipc_link_send_proto_msg(l_ptr,
-				STATE_MSG, 0, 0, new_value, 0, 0);
-			break;
-		case TIPC_CMD_SET_LINK_PRI:
-			l_ptr->priority = new_value;
-			tipc_link_send_proto_msg(l_ptr,
-				STATE_MSG, 0, 0, 0, new_value, 0);
-			break;
-		case TIPC_CMD_SET_LINK_WINDOW:
-			tipc_link_set_queue_limits(l_ptr, new_value);
-			break;
-		default:
-			res = -EINVAL;
-			break;
+		l_ptr = node->links[bearer_id];
+
+		if (l_ptr) {
+			switch (cmd) {
+			case TIPC_CMD_SET_LINK_TOL:
+				link_set_supervision_props(l_ptr, new_value);
+				tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0,
+							 0, new_value, 0, 0);
+				break;
+			case TIPC_CMD_SET_LINK_PRI:
+				l_ptr->priority = new_value;
+				tipc_link_send_proto_msg(l_ptr, STATE_MSG, 0,
+							 0, 0, new_value, 0);
+				break;
+			case TIPC_CMD_SET_LINK_WINDOW:
+				tipc_link_set_queue_limits(l_ptr, new_value);
+				break;
+			default:
+				res = -EINVAL;
+				break;
+			}
 		}
 		tipc_node_unlock(node);
 		return res;
@@ -2579,6 +2585,7 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
 	char *link_name;
 	struct tipc_link *l_ptr;
 	struct tipc_node *node;
+	unsigned int bearer_id;
 
 	if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
 		return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -2589,15 +2596,19 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
 			return tipc_cfg_reply_error_string("link not found");
 		return tipc_cfg_reply_none();
 	}
-
 	read_lock_bh(&tipc_net_lock);
-	l_ptr = link_find_link(link_name, &node);
+	node = tipc_link_find_owner(link_name, &bearer_id);
+	if (!node) {
+		read_unlock_bh(&tipc_net_lock);
+		return tipc_cfg_reply_error_string("link not found");
+	}
+	spin_lock(&node->lock);
+	l_ptr = node->links[bearer_id];
 	if (!l_ptr) {
+		tipc_node_unlock(node);
 		read_unlock_bh(&tipc_net_lock);
 		return tipc_cfg_reply_error_string("link not found");
 	}
-
-	tipc_node_lock(node);
 	link_reset_statistics(l_ptr);
 	tipc_node_unlock(node);
 	read_unlock_bh(&tipc_net_lock);
@@ -2627,18 +2638,27 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
 	struct tipc_node *node;
 	char *status;
 	u32 profile_total = 0;
+	unsigned int bearer_id;
 	int ret;
 
 	if (!strcmp(name, tipc_bclink_name))
 		return tipc_bclink_stats(buf, buf_size);
 
 	read_lock_bh(&tipc_net_lock);
-	l = link_find_link(name, &node);
-	if (!l) {
+	node = tipc_link_find_owner(name, &bearer_id);
+	if (!node) {
 		read_unlock_bh(&tipc_net_lock);
 		return 0;
 	}
 	tipc_node_lock(node);
+
+	l = node->links[bearer_id];
+	if (!l) {
+		tipc_node_unlock(node);
+		read_unlock_bh(&tipc_net_lock);
+		return 0;
+	}
+
 	s = &l->stats;
 
 	if (tipc_link_is_active(l))
-- 
1.7.9.5


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk

^ permalink raw reply related

* Re: [PATCH net 1/3] kref: add kref_sub_return
From: Greg Kroah-Hartman @ 2014-02-12 18:37 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: virtio-dev, Joern Engel, Anatol Pomozov, netdev, linux-kernel,
	virtualization, qinchuanyu, davem
In-Reply-To: <20140212173524.GA26860@redhat.com>

On Wed, Feb 12, 2014 at 07:35:24PM +0200, Michael S. Tsirkin wrote:
> On Wed, Feb 12, 2014 at 08:56:30AM -0800, Greg Kroah-Hartman wrote:
> > On Wed, Feb 12, 2014 at 06:38:21PM +0200, Michael S. Tsirkin wrote:
> > > It is sometimes useful to get the value of the reference count after
> > > decrement.
> > > For example, vhost wants to execute some periodic cleanup operations
> > > once number of references drops below a specific value, before it
> > > reaches zero (for efficiency).
> > 
> > You should never care about what the value of the kref is, if you are
> > using it correctly :)
> > 
> > So I really don't want to add this function, as I'm sure people will use
> > it incorrectly.  You should only care if the reference drops to 0, if
> > not, then your usage doesn't really fit into the "kref" model, and so,
> > just use an atomic variable.
> 
> This happens when you have code that keeps
> reference itself implicitly or explicitly.
> 
> 	foo(struct kref *k, int bar) {
> 
> 	sub = kref_sub(k)
> 
> 	if (sub == 1)
> 		FOO(k, bar) /* Here I am the only one
> 			       with a reference */

Why do you care if you are the only one with a reference?

If you do, then just don't grab that reference and do the work in the
cleanup callback :)

> 	}
> 
> 	kref_get(k)
> 	foo(k, bar);
> 	....
> 	kref_put(k)
> 
> Why not do FOO in destructor you ask?
> Absolutely but this will be called much later.
> 
> Maybe you will reconsider if I document this
> as the only legal use?

No one reads documentation :(

> > I really want to know why it matters for "efficiency" that you know this
> > number.  How does that help anything, as the number could then go up
> > later on, and the work you did at a "lower" number is obsolete, right?
> > 
> > thanks,
> > 
> > greg k-h
> 
> The issue is that if number dropped to 1, this means
> we must do the cleanup work since there are
> no outstanding buffers, (last user is ourselves)
> if we do not cleanup,
> guest will hang waiting for us.

This doesn't make sense, nor does it sound like a use for a kref (or you
are using it wrong.)

> But it never drops to 0 since we have our own reference
> in the device.

Then don't do that.

> If it goes up again this means we didn't have
> to do cleanup, but an alternative is doing
> it all the time and that is slow.

Then just cleanup when it hits 0, like the rest of the world does.

> Yes I can rework vhost to open-code this kref use, it's
> no big deal.
> Alternatively since most of the use does match kref
> model, maybe __kref_sub_return with disclaimers
> that you must know what you are doing?

No, no one reads documentation, sorry.  Either fix your use of kref
(i.e. don't care about the count), or do something else, as you don't
want a kref, but rather, an atomic count of what is going on and "1"
means something "special" to you.

sorry,

greg k-h

^ permalink raw reply

* Re: [PATCH net 1/3] kref: add kref_sub_return
From: Anatol Pomozov @ 2014-02-12 18:39 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Greg Kroah-Hartman, LKML, Jason Wang, virtio-dev, virtualization,
	netdev, davem, qinchuanyu, Joern Engel, Nicholas Bellinger
In-Reply-To: <20140212173524.GA26860@redhat.com>

Hi

On Wed, Feb 12, 2014 at 9:35 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Wed, Feb 12, 2014 at 08:56:30AM -0800, Greg Kroah-Hartman wrote:
>> On Wed, Feb 12, 2014 at 06:38:21PM +0200, Michael S. Tsirkin wrote:
>> > It is sometimes useful to get the value of the reference count after
>> > decrement.
>> > For example, vhost wants to execute some periodic cleanup operations
>> > once number of references drops below a specific value, before it
>> > reaches zero (for efficiency).
>>
>> You should never care about what the value of the kref is, if you are
>> using it correctly :)
>>
>> So I really don't want to add this function, as I'm sure people will use
>> it incorrectly.  You should only care if the reference drops to 0, if
>> not, then your usage doesn't really fit into the "kref" model, and so,
>> just use an atomic variable.
>
> This happens when you have code that keeps
> reference itself implicitly or explicitly.
>
>         foo(struct kref *k, int bar) {
>
>         sub = kref_sub(k)
>
>         if (sub == 1)

At this moment you cannot be sure that refcount is 1. It might be
changed between kref_sub call and this point. The refcount might be 0,
1, ... or any other value.

The only value that you can be sure is zero. Once refcount becomes
zero there is no way to increase it to positive value as there are no
alive pointers to the object.

>                 FOO(k, bar) /* Here I am the only one
>                                with a reference */
>
>         }
>
>         kref_get(k)
>         foo(k, bar);
>         ....
>         kref_put(k)
>
> Why not do FOO in destructor you ask?
> Absolutely but this will be called much later.
>
> Maybe you will reconsider if I document this
> as the only legal use?
>
>>
>> I really want to know why it matters for "efficiency" that you know this
>> number.  How does that help anything, as the number could then go up
>> later on, and the work you did at a "lower" number is obsolete, right?
>>
>> thanks,
>>
>> greg k-h
>
> The issue is that if number dropped to 1, this means
> we must do the cleanup work since there are
> no outstanding buffers, (last user is ourselves)
> if we do not cleanup,
> guest will hang waiting for us.
>
> But it never drops to 0 since we have our own reference
> in the device.
> If it goes up again this means we didn't have
> to do cleanup, but an alternative is doing
> it all the time and that is slow.
>
> Yes I can rework vhost to open-code this kref use, it's
> no big deal.
> Alternatively since most of the use does match kref
> model, maybe __kref_sub_return with disclaimers
> that you must know what you are doing?
> Please let me know.
>
> Thanks!
>
> --
> MST

^ permalink raw reply

* Re: RFC: bridge get fdb by bridge device
From: John Fastabend @ 2014-02-12 18:50 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: vyasevic, netdev@vger.kernel.org, Stephen Hemminger,
	Scott Feldman
In-Reply-To: <52FA9074.2060900@mojatatu.com>

On 2/11/2014 1:04 PM, Jamal Hadi Salim wrote:
> On 02/11/14 15:30, John Fastabend wrote:
>> On 2/11/2014 12:15 PM, Jamal Hadi Salim wrote:
>
> Thanks for the example on the other email.
>

Just to wrap things up in one email. Changing between VEB and VEPA
modes already triggers an event. So management applications can listen
for this.

And I can send out a patch to add a flag to hardware bridge devices
I'll likely get to it next week sometime unless someone beats me
to it.

>
>> What do you mean by "bridge device" are you specifically talking about
>> IFF_BRIDGE flag? This flag is used only for ./net/bridge devices.
>
> Right - the simple definition is this thing has an fdb.
> Yes, I know weve added vlan filtering and multicast snooping
> but thats all lipstick. If it has an (ethernet) fdb it is a bridge.
>

Sure, IEEE802.1Q would call these edge relays.

>> For
>> example macvlan uses its own flag. I think there is a good case to be
>> made for netdevices which are acting as the management interface for a
>> hardware bridge to set an identifying flag. Perhaps IFF_HWBRIDGE.
>>
>
> If you introduce IFF_HWBRIDGE - I think that would satisfy the
> distinction. The question then is why not just tag it IFF_BRIDGE?
>

Because it is not the same type of object as the software bridge.
Most notably it doesn't do learning. If anything its more like a
macvlan device and we could just as easily tag it IFF_MACVLAN. So
because it doesn't really match 1:1 with either of those object I
would just presume give its own flag. Userspace can always create
a small macro call it is_bridge_like() and check for any of the
handful of bridge like objects.

>>
>> # ip link set dev bridge0 master bridge1
>> RTNETLINK answers: Too many levels of symbolic links
>>
>
> pourquoi?  If the original rationale was to limit the
> broadcast domain scope it sounds strange that a bridge in
> the form a macvlan is allowed.
>

Agreed. But there it is.

>> in the bridge case this doesn't work. But you can stack a macvlan
>> on top of the bridge port,
>>
>> # ip link add link bridge0 type macvlan mode vepa
>>
>> 11: macvlan0@bridge0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop
>> state DOWN mode DEFAULT group default
>>
>> And macvlans on macvlans is OK as well.
>>
>> # ip link add link macvlan0 type macvlan mode vepa
>>
>> [...]
>>
>
> Ok, I need to let that sink in. Cool actually.
>

Also note you can mix VEB and VEPA modes and if you do it correctly
can create blocks of virtual ports that can do east-west traffic and
isolate others.

>
>>
>> If its useful then we should. You can track them down in userspace
>> via /sys/class/net/ or looking for offloaded netdevices that point
>> to the interface but a flag is definitely more direct.
>>
>
> I prefer a flag. Then i can deal with it via netlink.
>

OK. I'll add one here shortly.

> cheers,
> jamal
>

^ permalink raw reply

* [PATCH net-next 00/13] Cleanup patches for the SFC driver
From: Shradha Shah @ 2014-02-12 18:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-net-drivers

This patch set consists of some cleanup and housekeeping
patches for the sfc driver.
These patches help to reduce the differences between the in-
tree and out-of-tree driver.

Ben Hutchings (12):
  sfc: Cache skb->data in local variable in efx_ptp_rx()
  sfc: Rewrite adjustment of PPS event in a clearer way
  sfc: Replace TSOH_OFFSET with the equivalent NET_IP_ALIGN
  sfc: Rename 'use_options' variable in tso_start() to clearer
    'use_opt_desc'
  sfc: Remove unused definitions of EF10 user-mode DMA descriptors
  sfc: Correct comment about number of TX queues used on EF10
  sfc: Preserve rx_frm_trunc counters when resizing DMA rings
  sfc: Use canonical pointer type for MAC address in
    efx_set_mac_address()
  sfc: Update product naming
  sfc: Cosmetic changes to self-test from the out-of-tree driver
  sfc: Fail self-test with -EBUSY, not -EIO, if the device is busy
  sfc: Add/remove blank lines to taste

Laurence Evans (1):
  sfc: Removed adhoc scheme to rate limit PTP event queue overflow
    message

 drivers/net/ethernet/sfc/ef10.c       |    4 +-
 drivers/net/ethernet/sfc/ef10_regs.h  |   61 ----------------------
 drivers/net/ethernet/sfc/efx.c        |    6 +--
 drivers/net/ethernet/sfc/efx.h        |    2 +-
 drivers/net/ethernet/sfc/ethtool.c    |   21 +++++---
 drivers/net/ethernet/sfc/falcon.c     |    4 +-
 drivers/net/ethernet/sfc/farch.c      |    2 -
 drivers/net/ethernet/sfc/net_driver.h |    1 -
 drivers/net/ethernet/sfc/nic.c        |    1 -
 drivers/net/ethernet/sfc/ptp.c        |   92 ++++++++++++++-------------------
 drivers/net/ethernet/sfc/tx.c         |   21 ++-----
 11 files changed, 65 insertions(+), 150 deletions(-)

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox