Explorar o código

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

David S. Miller %!s(int64=15) %!d(string=hai) anos
pai
achega
0448873480

+ 4 - 4
Documentation/networking/ip-sysctl.txt

@@ -1126,10 +1126,10 @@ regen_max_retry - INTEGER
 	Default: 5
 	Default: 5
 
 
 max_addresses - INTEGER
 max_addresses - INTEGER
-	Number of maximum addresses per interface.  0 disables limitation.
-	It is recommended not set too large value (or 0) because it would
-	be too easy way to crash kernel to allow to create too much of
-	autoconfigured addresses.
+	Maximum number of autoconfigured addresses per interface.  Setting
+	to zero disables the limitation.  It is not recommended to set this
+	value too large (or to zero) because it would be an easy way to
+	crash the kernel by allowing too many addresses to be created.
 	Default: 16
 	Default: 16
 
 
 disable_ipv6 - BOOLEAN
 disable_ipv6 - BOOLEAN

+ 2 - 2
MAINTAINERS

@@ -3495,9 +3495,9 @@ S:	Maintained
 F:	drivers/net/wireless/libertas/
 F:	drivers/net/wireless/libertas/
 
 
 MARVELL MV643XX ETHERNET DRIVER
 MARVELL MV643XX ETHERNET DRIVER
-M:	Lennert Buytenhek <buytenh@marvell.com>
+M:	Lennert Buytenhek <buytenh@wantstofly.org>
 L:	netdev@vger.kernel.org
 L:	netdev@vger.kernel.org
-S:	Supported
+S:	Maintained
 F:	drivers/net/mv643xx_eth.*
 F:	drivers/net/mv643xx_eth.*
 F:	include/linux/mv643xx.h
 F:	include/linux/mv643xx.h
 
 

+ 18 - 1
drivers/net/e1000/e1000_main.c

@@ -4005,11 +4005,21 @@ check_page:
 			}
 			}
 		}
 		}
 
 
-		if (!buffer_info->dma)
+		if (!buffer_info->dma) {
 			buffer_info->dma = pci_map_page(pdev,
 			buffer_info->dma = pci_map_page(pdev,
 			                                buffer_info->page, 0,
 			                                buffer_info->page, 0,
 			                                buffer_info->length,
 			                                buffer_info->length,
 			                                PCI_DMA_FROMDEVICE);
 			                                PCI_DMA_FROMDEVICE);
+			if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+				put_page(buffer_info->page);
+				dev_kfree_skb(skb);
+				buffer_info->page = NULL;
+				buffer_info->skb = NULL;
+				buffer_info->dma = 0;
+				adapter->alloc_rx_buff_failed++;
+				break; /* while !buffer_info->skb */
+			}
+		}
 
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -4100,6 +4110,13 @@ map_skb:
 						  skb->data,
 						  skb->data,
 						  buffer_info->length,
 						  buffer_info->length,
 						  PCI_DMA_FROMDEVICE);
 						  PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
+			dev_kfree_skb(skb);
+			buffer_info->skb = NULL;
+			buffer_info->dma = 0;
+			adapter->alloc_rx_buff_failed++;
+			break; /* while !buffer_info->skb */
+		}
 
 
 		/*
 		/*
 		 * XXX if it was allocated cleanly it will never map to a
 		 * XXX if it was allocated cleanly it will never map to a

+ 27 - 18
drivers/net/sfc/falcon_boards.c

@@ -29,6 +29,15 @@
 #define FALCON_BOARD_SFN4111T 0x51
 #define FALCON_BOARD_SFN4111T 0x51
 #define FALCON_BOARD_SFN4112F 0x52
 #define FALCON_BOARD_SFN4112F 0x52
 
 
+/* Board temperature is about 15°C above ambient when air flow is
+ * limited. */
+#define FALCON_BOARD_TEMP_BIAS	15
+
+/* SFC4000 datasheet says: 'The maximum permitted junction temperature
+ * is 125°C; the thermal design of the environment for the SFC4000
+ * should aim to keep this well below 100°C.' */
+#define FALCON_JUNC_TEMP_MAX	90
+
 /*****************************************************************************
 /*****************************************************************************
  * Support for LM87 sensor chip used on several boards
  * Support for LM87 sensor chip used on several boards
  */
  */
@@ -548,16 +557,16 @@ fail_hwmon:
 static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
 static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
 
 
 static const u8 sfe4002_lm87_regs[] = {
 static const u8 sfe4002_lm87_regs[] = {
-	LM87_IN_LIMITS(0, 0x83, 0x91),		/* 2.5V:  1.8V +/- 5% */
-	LM87_IN_LIMITS(1, 0x51, 0x5a),		/* Vccp1: 1.2V +/- 5% */
-	LM87_IN_LIMITS(2, 0xb6, 0xca),		/* 3.3V:  3.3V +/- 5% */
-	LM87_IN_LIMITS(3, 0xb0, 0xc9),		/* 5V:    4.6-5.2V */
-	LM87_IN_LIMITS(4, 0xb0, 0xe0),		/* 12V:   11-14V */
-	LM87_IN_LIMITS(5, 0x44, 0x4b),		/* Vccp2: 1.0V +/- 5% */
-	LM87_AIN_LIMITS(0, 0xa0, 0xb2),		/* AIN1:  1.66V +/- 5% */
-	LM87_AIN_LIMITS(1, 0x91, 0xa1),		/* AIN2:  1.5V +/- 5% */
-	LM87_TEMP_INT_LIMITS(10, 60),		/* board */
-	LM87_TEMP_EXT1_LIMITS(10, 70),		/* Falcon */
+	LM87_IN_LIMITS(0, 0x7c, 0x99),		/* 2.5V:  1.8V +/- 10% */
+	LM87_IN_LIMITS(1, 0x4c, 0x5e),		/* Vccp1: 1.2V +/- 10% */
+	LM87_IN_LIMITS(2, 0xac, 0xd4),		/* 3.3V:  3.3V +/- 10% */
+	LM87_IN_LIMITS(3, 0xac, 0xd4),		/* 5V:    5.0V +/- 10% */
+	LM87_IN_LIMITS(4, 0xac, 0xe0),		/* 12V:   10.8-14V */
+	LM87_IN_LIMITS(5, 0x3f, 0x4f),		/* Vccp2: 1.0V +/- 10% */
+	LM87_AIN_LIMITS(0, 0x98, 0xbb),		/* AIN1:  1.66V +/- 10% */
+	LM87_AIN_LIMITS(1, 0x8a, 0xa9),		/* AIN2:  1.5V +/- 10% */
+	LM87_TEMP_INT_LIMITS(0, 80 + FALCON_BOARD_TEMP_BIAS),
+	LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
 	0
 	0
 };
 };
 
 
@@ -619,14 +628,14 @@ static int sfe4002_init(struct efx_nic *efx)
 static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
 static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
 
 
 static const u8 sfn4112f_lm87_regs[] = {
 static const u8 sfn4112f_lm87_regs[] = {
-	LM87_IN_LIMITS(0, 0x83, 0x91),		/* 2.5V:  1.8V +/- 5% */
-	LM87_IN_LIMITS(1, 0x51, 0x5a),		/* Vccp1: 1.2V +/- 5% */
-	LM87_IN_LIMITS(2, 0xb6, 0xca),		/* 3.3V:  3.3V +/- 5% */
-	LM87_IN_LIMITS(4, 0xb0, 0xe0),		/* 12V:   11-14V */
-	LM87_IN_LIMITS(5, 0x44, 0x4b),		/* Vccp2: 1.0V +/- 5% */
-	LM87_AIN_LIMITS(1, 0x91, 0xa1),		/* AIN2:  1.5V +/- 5% */
-	LM87_TEMP_INT_LIMITS(10, 60),		/* board */
-	LM87_TEMP_EXT1_LIMITS(10, 70),		/* Falcon */
+	LM87_IN_LIMITS(0, 0x7c, 0x99),		/* 2.5V:  1.8V +/- 10% */
+	LM87_IN_LIMITS(1, 0x4c, 0x5e),		/* Vccp1: 1.2V +/- 10% */
+	LM87_IN_LIMITS(2, 0xac, 0xd4),		/* 3.3V:  3.3V +/- 10% */
+	LM87_IN_LIMITS(4, 0xac, 0xe0),		/* 12V:   10.8-14V */
+	LM87_IN_LIMITS(5, 0x3f, 0x4f),		/* Vccp2: 1.0V +/- 10% */
+	LM87_AIN_LIMITS(1, 0x8a, 0xa9),		/* AIN2:  1.5V +/- 10% */
+	LM87_TEMP_INT_LIMITS(0, 60 + FALCON_BOARD_TEMP_BIAS),
+	LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
 	0
 	0
 };
 };
 
 

+ 1 - 1
drivers/net/sfc/mcdi.c

@@ -127,7 +127,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
 	efx_dword_t reg;
 	efx_dword_t reg;
 
 
 	/* Check for a reboot atomically with respect to efx_mcdi_copyout() */
 	/* Check for a reboot atomically with respect to efx_mcdi_copyout() */
-	rc = efx_mcdi_poll_reboot(efx);
+	rc = -efx_mcdi_poll_reboot(efx);
 	if (rc)
 	if (rc)
 		goto out;
 		goto out;
 
 

+ 0 - 1
drivers/net/tc35815.c

@@ -1437,7 +1437,6 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status, int limit)
 		/* Transmit complete. */
 		/* Transmit complete. */
 		lp->lstats.tx_ints++;
 		lp->lstats.tx_ints++;
 		tc35815_txdone(dev);
 		tc35815_txdone(dev);
-		netif_wake_queue(dev);
 		if (ret < 0)
 		if (ret < 0)
 			ret = 0;
 			ret = 0;
 	}
 	}

+ 5 - 0
drivers/net/usb/cdc_ether.c

@@ -581,6 +581,11 @@ static const struct usb_device_id	products [] = {
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
 	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x1049, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
 	.driver_info = (unsigned long) &mbm_info,
 	.driver_info = (unsigned long) &mbm_info,
+}, {
+	/* Ericsson C3607w ver 2 */
+	USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM,
+			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+	.driver_info = (unsigned long) &mbm_info,
 }, {
 }, {
 	/* Toshiba F3507g */
 	/* Toshiba F3507g */
 	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
 	USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-4965.c

@@ -2008,7 +2008,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
 			IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
 			IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
 					   "%d index %d\n", scd_ssn , index);
 					   "%d index %d\n", scd_ssn , index);
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+			iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 
 			if (priv->mac80211_registered &&
 			if (priv->mac80211_registered &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&

+ 3 - 5
drivers/net/wireless/iwlwifi/iwl-5000.c

@@ -1116,7 +1116,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
 					scd_ssn , index, txq_id, txq->swq_id);
 					scd_ssn , index, txq_id, txq->swq_id);
 
 
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
 			freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+			iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 
 			if (priv->mac80211_registered &&
 			if (priv->mac80211_registered &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 			    (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -1144,16 +1144,14 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
 				   tx_resp->failure_frame);
 				   tx_resp->failure_frame);
 
 
 		freed = iwl_tx_queue_reclaim(priv, txq_id, index);
 		freed = iwl_tx_queue_reclaim(priv, txq_id, index);
-		if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
-			priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+		iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 
 		if (priv->mac80211_registered &&
 		if (priv->mac80211_registered &&
 		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
 		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
 			iwl_wake_queue(priv, txq_id);
 			iwl_wake_queue(priv, txq_id);
 	}
 	}
 
 
-	if (ieee80211_is_data_qos(tx_resp->frame_ctrl))
-		iwl_txq_check_empty(priv, sta_id, tid, txq_id);
+	iwl_txq_check_empty(priv, sta_id, tid, txq_id);
 
 
 	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
 	if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
 		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");
 		IWL_ERR(priv, "TODO:  Implement Tx ABORT REQUIRED!!!\n");

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-core.c

@@ -2787,8 +2787,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 		if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
 		if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
 			priv->staging_rxon.flags = 0;
 			priv->staging_rxon.flags = 0;
 
 
-		iwl_set_rxon_ht(priv, ht_conf);
 		iwl_set_rxon_channel(priv, conf->channel);
 		iwl_set_rxon_channel(priv, conf->channel);
+		iwl_set_rxon_ht(priv, ht_conf);
 
 
 		iwl_set_flags_for_band(priv, conf->channel->band);
 		iwl_set_flags_for_band(priv, conf->channel->band);
 		spin_unlock_irqrestore(&priv->lock, flags);
 		spin_unlock_irqrestore(&priv->lock, flags);

+ 2 - 0
drivers/net/wireless/iwlwifi/iwl-core.h

@@ -451,6 +451,8 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
 int iwl_hw_tx_queue_init(struct iwl_priv *priv,
 int iwl_hw_tx_queue_init(struct iwl_priv *priv,
 			 struct iwl_tx_queue *txq);
 			 struct iwl_tx_queue *txq);
 int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
 int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+			    int sta_id, int tid, int freed);
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
 		      int slots_num, u32 txq_id);
 		      int slots_num, u32 txq_id);
 void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
 void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);

+ 20 - 2
drivers/net/wireless/iwlwifi/iwl-tx.c

@@ -120,6 +120,20 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 EXPORT_SYMBOL(iwl_txq_update_write_ptr);
 EXPORT_SYMBOL(iwl_txq_update_write_ptr);
 
 
 
 
+void iwl_free_tfds_in_queue(struct iwl_priv *priv,
+			    int sta_id, int tid, int freed)
+{
+	if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
+		priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+	else {
+		IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
+			priv->stations[sta_id].tid[tid].tfds_in_queue,
+			freed);
+		priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
+	}
+}
+EXPORT_SYMBOL(iwl_free_tfds_in_queue);
+
 /**
 /**
  * iwl_tx_queue_free - Deallocate DMA queue.
  * iwl_tx_queue_free - Deallocate DMA queue.
  * @txq: Transmit queue to deallocate.
  * @txq: Transmit queue to deallocate.
@@ -1131,6 +1145,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
 	struct iwl_queue *q = &txq->q;
 	struct iwl_queue *q = &txq->q;
 	struct iwl_tx_info *tx_info;
 	struct iwl_tx_info *tx_info;
 	int nfreed = 0;
 	int nfreed = 0;
+	struct ieee80211_hdr *hdr;
 
 
 	if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
 	if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
 		IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
 		IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
@@ -1145,13 +1160,16 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
 
 
 		tx_info = &txq->txb[txq->q.read_ptr];
 		tx_info = &txq->txb[txq->q.read_ptr];
 		iwl_tx_status(priv, tx_info->skb[0]);
 		iwl_tx_status(priv, tx_info->skb[0]);
+
+		hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
+		if (hdr && ieee80211_is_data_qos(hdr->frame_control))
+			nfreed++;
 		tx_info->skb[0] = NULL;
 		tx_info->skb[0] = NULL;
 
 
 		if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
 		if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
 			priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
 			priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
 
 
 		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
 		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
-		nfreed++;
 	}
 	}
 	return nfreed;
 	return nfreed;
 }
 }
@@ -1559,7 +1577,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
 	if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
 	if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
 		/* calculate mac80211 ampdu sw queue to wake */
 		/* calculate mac80211 ampdu sw queue to wake */
 		int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
 		int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
-		priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
+		iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 
 		if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 		if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
 		    priv->mac80211_registered &&
 		    priv->mac80211_registered &&

+ 2 - 1
net/core/net-sysfs.c

@@ -410,7 +410,8 @@ static ssize_t wireless_show(struct device *d, char *buf,
 	const struct iw_statistics *iw;
 	const struct iw_statistics *iw;
 	ssize_t ret = -EINVAL;
 	ssize_t ret = -EINVAL;
 
 
-	rtnl_lock();
+	if (!rtnl_trylock())
+		return restart_syscall();
 	if (dev_isalive(dev)) {
 	if (dev_isalive(dev)) {
 		iw = get_wireless_stats(dev);
 		iw = get_wireless_stats(dev);
 		if (iw)
 		if (iw)

+ 6 - 1
net/ipv4/devinet.c

@@ -1317,14 +1317,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
 {
 {
 	int *valp = ctl->data;
 	int *valp = ctl->data;
 	int val = *valp;
 	int val = *valp;
+	loff_t pos = *ppos;
 	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 
 
 	if (write && *valp != val) {
 	if (write && *valp != val) {
 		struct net *net = ctl->extra2;
 		struct net *net = ctl->extra2;
 
 
 		if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
 		if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
-			if (!rtnl_trylock())
+			if (!rtnl_trylock()) {
+				/* Restore the original values before restarting */
+				*valp = val;
+				*ppos = pos;
 				return restart_syscall();
 				return restart_syscall();
+			}
 			if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
 			if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
 				inet_forward_change(net);
 				inet_forward_change(net);
 			} else if (*valp) {
 			} else if (*valp) {

+ 14 - 2
net/ipv6/addrconf.c

@@ -502,8 +502,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
 	if (p == &net->ipv6.devconf_dflt->forwarding)
 	if (p == &net->ipv6.devconf_dflt->forwarding)
 		return 0;
 		return 0;
 
 
-	if (!rtnl_trylock())
+	if (!rtnl_trylock()) {
+		/* Restore the original values before restarting */
+		*p = old;
 		return restart_syscall();
 		return restart_syscall();
+	}
 
 
 	if (p == &net->ipv6.devconf_all->forwarding) {
 	if (p == &net->ipv6.devconf_all->forwarding) {
 		__s32 newf = net->ipv6.devconf_all->forwarding;
 		__s32 newf = net->ipv6.devconf_all->forwarding;
@@ -4042,12 +4045,15 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
 {
 {
 	int *valp = ctl->data;
 	int *valp = ctl->data;
 	int val = *valp;
 	int val = *valp;
+	loff_t pos = *ppos;
 	int ret;
 	int ret;
 
 
 	ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 	ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 
 
 	if (write)
 	if (write)
 		ret = addrconf_fixup_forwarding(ctl, valp, val);
 		ret = addrconf_fixup_forwarding(ctl, valp, val);
+	if (ret)
+		*ppos = pos;
 	return ret;
 	return ret;
 }
 }
 
 
@@ -4089,8 +4095,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
 	if (p == &net->ipv6.devconf_dflt->disable_ipv6)
 	if (p == &net->ipv6.devconf_dflt->disable_ipv6)
 		return 0;
 		return 0;
 
 
-	if (!rtnl_trylock())
+	if (!rtnl_trylock()) {
+		/* Restore the original values before restarting */
+		*p = old;
 		return restart_syscall();
 		return restart_syscall();
+	}
 
 
 	if (p == &net->ipv6.devconf_all->disable_ipv6) {
 	if (p == &net->ipv6.devconf_all->disable_ipv6) {
 		__s32 newf = net->ipv6.devconf_all->disable_ipv6;
 		__s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@ -4109,12 +4118,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
 {
 {
 	int *valp = ctl->data;
 	int *valp = ctl->data;
 	int val = *valp;
 	int val = *valp;
+	loff_t pos = *ppos;
 	int ret;
 	int ret;
 
 
 	ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 	ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 
 
 	if (write)
 	if (write)
 		ret = addrconf_disable_ipv6(ctl, valp, val);
 		ret = addrconf_disable_ipv6(ctl, valp, val);
+	if (ret)
+		*ppos = pos;
 	return ret;
 	return ret;
 }
 }