linux-next: manual merge of the net-next tree with the wireless tree

2 messages, 2 authors, 2012-05-04 · open the first message on its own page

linux-next: manual merge of the net-next tree with the wireless tree

From: Stephen Rothwell <hidden>
Date: 2012-05-04 03:21:51

Hi all,

Today's linux-next merge of the net-next tree got conflicts in
drivers/net/wireless/iwlwifi/iwl-trans.h,
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c, and
drivers/net/wireless/iwlwifi/iwl-agn-rx.c between commit ed90542b0ce5
("iwlwifi: fix skb truesize underestimation") from the wireless tree and
various commits from the net-next tree.

This was anticipated and I have applied the fix supplied by John (see
below just to check).  Thanks to John for this!
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 2247460,f941223..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@@ -787,25 -752,15 +751,24 @@@ static void iwlagn_pass_packet_to_mac80
  	    iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats))
  		return;
  
 -	skb = dev_alloc_skb(128);
 +	/* Dont use dev_alloc_skb(), we'll have enough headroom once
 +	 * ieee80211_hdr pulled.
 +	 */
 +	skb = alloc_skb(128, GFP_ATOMIC);
  	if (!skb) {
 -		IWL_ERR(priv, "dev_alloc_skb failed\n");
 +		IWL_ERR(priv, "alloc_skb failed\n");
  		return;
  	}
 +	hdrlen = min_t(unsigned int, len, skb_tailroom(skb));
 +	memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
 +	fraglen = len - hdrlen;
 +
 +	if (fraglen) {
- 		int offset = (void *)hdr + hdrlen - rxb_addr(rxb);
++		int offset = (void *)hdr - rxb_addr(rxb) + rxb_offset(rxb);
  
 -	offset = (void *)hdr - rxb_addr(rxb) + rxb_offset(rxb);
 -	p = rxb_steal_page(rxb);
 -	skb_add_rx_frag(skb, 0, p, offset, len, len);
 +		skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
 +				fraglen, rxb->truesize);
 +	}
- 	iwl_update_stats(priv, false, fc, len);
  
  	/*
  	* Wake any queues that were stopped due to a passive channel tx
diff --cc drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
index aa7aea1,d2239aa..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
@@@ -374,72 -373,89 +373,90 @@@ static void iwl_rx_handle_rxbuf(struct 
  	if (WARN_ON(!rxb))
  		return;
  
- 	rxcb.truesize = PAGE_SIZE << hw_params(trans).rx_page_order;
- 	dma_unmap_page(trans->dev, rxb->page_dma,
- 		       rxcb.truesize,
- 		       DMA_FROM_DEVICE);
- 
- 	rxcb._page = rxb->page;
- 	pkt = rxb_addr(&rxcb);
- 
- 	IWL_DEBUG_RX(trans, "%s, 0x%02x\n",
- 		     get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
+ 	dma_unmap_page(trans->dev, rxb->page_dma, max_len, DMA_FROM_DEVICE);
  
+ 	while (offset + sizeof(u32) + sizeof(struct iwl_cmd_header) < max_len) {
+ 		struct iwl_rx_packet *pkt;
+ 		struct iwl_device_cmd *cmd;
+ 		u16 sequence;
+ 		bool reclaim;
+ 		int index, cmd_index, err, len;
+ 		struct iwl_rx_cmd_buffer rxcb = {
+ 			._offset = offset,
+ 			._page = rxb->page,
+ 			._page_stolen = false,
++			.truesize = max_len,
+ 		};
  
- 	len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- 	len += sizeof(u32); /* account for status word */
- 	trace_iwlwifi_dev_rx(trans->dev, pkt, len);
+ 		pkt = rxb_addr(&rxcb);
  
- 	/* Reclaim a command buffer only if this packet is a response
- 	 *   to a (driver-originated) command.
- 	 * If the packet (e.g. Rx frame) originated from uCode,
- 	 *   there is no command buffer to reclaim.
- 	 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
- 	 *   but apparently a few don't get set; catch them here. */
- 	reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
- 	if (reclaim) {
- 		int i;
+ 		if (pkt->len_n_flags == cpu_to_le32(FH_RSCSR_FRAME_INVALID))
+ 			break;
  
- 		for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
- 			if (trans_pcie->no_reclaim_cmds[i] == pkt->hdr.cmd) {
- 				reclaim = false;
- 				break;
+ 		IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n",
+ 			rxcb._offset,
+ 			trans_pcie_get_cmd_string(trans_pcie, pkt->hdr.cmd),
+ 			pkt->hdr.cmd);
+ 
+ 		len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ 		len += sizeof(u32); /* account for status word */
+ 		trace_iwlwifi_dev_rx(trans->dev, pkt, len);
+ 
+ 		/* Reclaim a command buffer only if this packet is a response
+ 		 *   to a (driver-originated) command.
+ 		 * If the packet (e.g. Rx frame) originated from uCode,
+ 		 *   there is no command buffer to reclaim.
+ 		 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
+ 		 *   but apparently a few don't get set; catch them here. */
+ 		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME);
+ 		if (reclaim) {
+ 			int i;
+ 
+ 			for (i = 0; i < trans_pcie->n_no_reclaim_cmds; i++) {
+ 				if (trans_pcie->no_reclaim_cmds[i] ==
+ 							pkt->hdr.cmd) {
+ 					reclaim = false;
+ 					break;
+ 				}
  			}
  		}
- 	}
  
- 	sequence = le16_to_cpu(pkt->hdr.sequence);
- 	index = SEQ_TO_INDEX(sequence);
- 	cmd_index = get_cmd_index(&txq->q, index);
+ 		sequence = le16_to_cpu(pkt->hdr.sequence);
+ 		index = SEQ_TO_INDEX(sequence);
+ 		cmd_index = get_cmd_index(&txq->q, index);
  
- 	if (reclaim)
- 		cmd = txq->cmd[cmd_index];
- 	else
- 		cmd = NULL;
+ 		if (reclaim)
+ 			cmd = txq->entries[cmd_index].cmd;
+ 		else
+ 			cmd = NULL;
  
- 	err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
+ 		err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
  
- 	/*
- 	 * XXX: After here, we should always check rxcb._page
- 	 * against NULL before touching it or its virtual
- 	 * memory (pkt). Because some rx_handler might have
- 	 * already taken or freed the pages.
- 	 */
+ 		/*
+ 		 * After here, we should always check rxcb._page_stolen,
+ 		 * if it is true then one of the handlers took the page.
+ 		 */
  
- 	if (reclaim) {
- 		/* Invoke any callbacks, transfer the buffer to caller,
- 		 * and fire off the (possibly) blocking
- 		 * iwl_trans_send_cmd()
- 		 * as we reclaim the driver command queue */
- 		if (rxcb._page)
- 			iwl_tx_cmd_complete(trans, &rxcb, err);
- 		else
- 			IWL_WARN(trans, "Claim null rxb?\n");
+ 		if (reclaim) {
+ 			/* Invoke any callbacks, transfer the buffer to caller,
+ 			 * and fire off the (possibly) blocking
+ 			 * iwl_trans_send_cmd()
+ 			 * as we reclaim the driver command queue */
+ 			if (!rxcb._page_stolen)
+ 				iwl_tx_cmd_complete(trans, &rxcb, err);
+ 			else
+ 				IWL_WARN(trans, "Claim null rxb?\n");
+ 		}
+ 
+ 		page_stolen |= rxcb._page_stolen;
+ 		offset += ALIGN(len, FH_RSCSR_FRAME_ALIGN);
  	}
  
- 	/* page was stolen from us */
- 	if (rxcb._page == NULL)
+ 	/* page was stolen from us -- free our reference */
+ 	if (page_stolen) {
+ 		__free_pages(rxb->page, trans_pcie->rx_page_order);
  		rxb->page = NULL;
+ 	}
  
  	/* Reuse the page if possible. For notification packets and
  	 * SKBs that fail to Rx correctly, add them back into the
diff --cc drivers/net/wireless/iwlwifi/iwl-trans.h
index fdf9788,7018d31..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@@ -260,7 -256,8 +256,9 @@@ static inline void iwl_free_resp(struc
  
  struct iwl_rx_cmd_buffer {
  	struct page *_page;
+ 	int _offset;
+ 	bool _page_stolen;
 +	unsigned int truesize;
  };
  
  static inline void *rxb_addr(struct iwl_rx_cmd_buffer *r)

Re: linux-next: manual merge of the net-next tree with the wireless tree

From: Guy, Wey-Yi <hidden>
Date: 2012-05-04 04:42:09

On Fri, 2012-05-04 at 13:21 +1000, Stephen Rothwell wrote:
Hi all,

Today's linux-next merge of the net-next tree got conflicts in
drivers/net/wireless/iwlwifi/iwl-trans.h,
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c, and
drivers/net/wireless/iwlwifi/iwl-agn-rx.c between commit ed90542b0ce5
("iwlwifi: fix skb truesize underestimation") from the wireless tree and
various commits from the net-next tree.

This was anticipated and I have applied the fix supplied by John (see
below just to check).  Thanks to John for this!
Thanks everyone to help address this, it is my miss to cause all these trouble

Wey
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help