Re: [Open-FCoE] [PATCH] bnx2fc: Improve stats update mechanism

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Thanks for fixing this.  The patch generally looks good, but I do have a
few comments.

On Fri, 2014-05-30 at 11:01 -0400, Neil Horman wrote:
> Recently had this warning reported:
> 
> [  290.489047] Call Trace:
> [  290.489053]  [<ffffffff8169efec>] dump_stack+0x19/0x1b
> [  290.489055]  [<ffffffff810ac7a9>] __might_sleep+0x179/0x230
> [  290.489057]  [<ffffffff816a4ad5>] mutex_lock_nested+0x55/0x520
> [  290.489061]  [<ffffffffa01b9905>] ? bnx2fc_l2_rcv_thread+0xc5/0x4c0 [bnx2fc]
> [  290.489065]  [<ffffffffa0174c1a>] fc_vport_id_lookup+0x3a/0xa0 [libfc]
> [  290.489068]  [<ffffffffa01b9a6c>] bnx2fc_l2_rcv_thread+0x22c/0x4c0 [bnx2fc]
> [  290.489070]  [<ffffffffa01b9840>] ? bnx2fc_vport_destroy+0x110/0x110 [bnx2fc]
> [  290.489073]  [<ffffffff8109e0cd>] kthread+0xed/0x100
> [  290.489075]  [<ffffffff8109dfe0>] ? insert_kthread_work+0x80/0x80
> [  290.489077]  [<ffffffff816b2fec>] ret_from_fork+0x7c/0xb0
> [  290.489078]  [<ffffffff8109dfe0>] ? insert_kthread_work+0x80/0x80
> 
> Its due to the fact that we call a potentially sleeping function from the bnx2fc
> rcv path with preemption disabled (via the get_cpu call embedded in the per-cpu
> variable stats lookup in bnx2fc_l2_rcv_thread.
> 
> Easy enough fix, we can just move the stats collection later in the function
> where we are sure we won't preempt or sleep.  This also allows us to not have to
> enable pre-emption when doing a per-cpu lookup, since we're certain not to get
You mean this allows us to not have to 'disable' pre-emption, right? 

Can you elaborate on how we can be sure that we won't get preempted
immediately after retrieving the CPU variable?  I would think it'll be
okay to call get_cpu at this stage as there won't be any sleepable mutex
lock calls before the put_cpu.
> rescheduled.
> 
> Signed-off-by: Neil Horman <nhorman@xxxxxxxxxxxxx>
> CC: linux-scsi@xxxxxxxxxxxxxxx
> CC: Robert Love <robert.w.love@xxxxxxxxx>
> CC: Vasu Dev <vasu.dev@xxxxxxxxx>
> ---
>  drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 16 ++++------------
>  1 file changed, 4 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
> index 9b94850..475eee5 100644
> --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
> +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
> @@ -516,23 +516,17 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
>  	skb_pull(skb, sizeof(struct fcoe_hdr));
>  	fr_len = skb->len - sizeof(struct fcoe_crc_eof);
>  
> -	stats = per_cpu_ptr(lport->stats, get_cpu());
> -	stats->RxFrames++;
> -	stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
> -
>  	fp = (struct fc_frame *)skb;
>  	fc_frame_init(fp);
>  	fr_dev(fp) = lport;
>  	fr_sof(fp) = hp->fcoe_sof;
>  	if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
> -		put_cpu();
>  		kfree_skb(skb);
>  		return;
>  	}
>  	fr_eof(fp) = crc_eof.fcoe_eof;
>  	fr_crc(fp) = crc_eof.fcoe_crc32;
>  	if (pskb_trim(skb, fr_len)) {
> -		put_cpu();
>  		kfree_skb(skb);
>  		return;
>  	}
> @@ -544,7 +538,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
>  		port = lport_priv(vn_port);
>  		if (!ether_addr_equal(port->data_src_addr, dest_mac)) {
>  			BNX2FC_HBA_DBG(lport, "fpma mismatch\n");
> -			put_cpu();
>  			kfree_skb(skb);
>  			return;
>  		}
> @@ -552,7 +545,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
>  	if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
>  	    fh->fh_type == FC_TYPE_FCP) {
>  		/* Drop FCP data. We dont this in L2 path */
> -		put_cpu();
>  		kfree_skb(skb);
>  		return;
>  	}
> @@ -562,7 +554,6 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
>  		case ELS_LOGO:
>  			if (ntoh24(fh->fh_s_id) == FC_FID_FLOGI) {
>  				/* drop non-FIP LOGO */
> -				put_cpu();
>  				kfree_skb(skb);
>  				return;
>  			}
> @@ -572,22 +563,23 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
>  
>  	if (fh->fh_r_ctl == FC_RCTL_BA_ABTS) {
>  		/* Drop incoming ABTS */
> -		put_cpu();
>  		kfree_skb(skb);
>  		return;
>  	}
>  
> +	stats = per_cpu_ptr(lport->stats, smp_processor_id());
> +	stats->RxFrames++;
> +	stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
> +
>  	if (le32_to_cpu(fr_crc(fp)) !=
>  			~crc32(~0, skb->data, fr_len)) {
>  		if (stats->InvalidCRCCount < 5)
>  			printk(KERN_WARNING PFX "dropping frame with "
>  			       "CRC error\n");
>  		stats->InvalidCRCCount++;
> -		put_cpu();
>  		kfree_skb(skb);
>  		return;
>  	}
> -	put_cpu();
>  	fc_exch_recv(lport, fp);
>  }
>  


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux