struct sk_buff *skb;
 #ifdef CONFIG_SMP
        struct fcoe_percpu_s *p0;
-       unsigned targ_cpu = smp_processor_id();
+       unsigned targ_cpu = get_cpu();
 #endif /* CONFIG_SMP */
 
        FCOE_DBG("Destroying receive thread for CPU %d\n", cpu);
                        kfree_skb(skb);
                spin_unlock_bh(&p->fcoe_rx_list.lock);
        }
+       put_cpu();
 #else
        /*
         * This a non-SMP scenario where the singular Rx thread is
 
        return 0;
 err:
-       fc_lport_get_stats(lport)->ErrorFrames++;
-
+       per_cpu_ptr(lport->dev_stats, get_cpu())->ErrorFrames++;
+       put_cpu();
 err2:
        kfree_skb(skb);
        return -1;
                skb_shinfo(skb)->gso_size = 0;
        }
        /* update tx stats: regardless if LLD fails */
-       stats = fc_lport_get_stats(lport);
+       stats = per_cpu_ptr(lport->dev_stats, get_cpu());
        stats->TxFrames++;
        stats->TxWords += wlen;
+       put_cpu();
 
        /* send down to lld */
        fr_dev(fp) = lport;
        hp = (struct fcoe_hdr *) skb_network_header(skb);
        fh = (struct fc_frame_header *) skb_transport_header(skb);
 
-       stats = fc_lport_get_stats(lport);
+       stats = per_cpu_ptr(lport->dev_stats, get_cpu());
        if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
                if (stats->ErrorFrames < 5)
                        printk(KERN_WARNING "fcoe: FCoE version "
                               "initiator supports version "
                               "%x\n", FC_FCOE_DECAPS_VER(hp),
                               FC_FCOE_VER);
-               stats->ErrorFrames++;
-               kfree_skb(skb);
-               return;
+               goto drop;
        }
 
        skb_pull(skb, sizeof(struct fcoe_hdr));
        fr_sof(fp) = hp->fcoe_sof;
 
        /* Copy out the CRC and EOF trailer for access */
-       if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
-               kfree_skb(skb);
-               return;
-       }
+       if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof)))
+               goto drop;
        fr_eof(fp) = crc_eof.fcoe_eof;
        fr_crc(fp) = crc_eof.fcoe_crc32;
-       if (pskb_trim(skb, fr_len)) {
-               kfree_skb(skb);
-               return;
-       }
+       if (pskb_trim(skb, fr_len))
+               goto drop;
 
        /*
         * We only check CRC if no offload is available and if it is
                fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
 
        fh = fc_frame_header_get(fp);
-       if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
-           fh->fh_type == FC_TYPE_FCP) {
-               fc_exch_recv(lport, fp);
-               return;
-       }
-       if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+       if ((fh->fh_r_ctl != FC_RCTL_DD_SOL_DATA ||
+           fh->fh_type != FC_TYPE_FCP) &&
+           (fr_flags(fp) & FCPHF_CRC_UNCHECKED)) {
                if (le32_to_cpu(fr_crc(fp)) !=
                    ~crc32(~0, skb->data, fr_len)) {
                        if (stats->InvalidCRCCount < 5)
                                printk(KERN_WARNING "fcoe: dropping "
                                       "frame with CRC error\n");
                        stats->InvalidCRCCount++;
-                       stats->ErrorFrames++;
-                       fc_frame_free(fp);
-                       return;
+                       goto drop;
                }
                fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
        }
+       put_cpu();
        fc_exch_recv(lport, fp);
+       return;
+
+drop:
+       stats->ErrorFrames++;
+       put_cpu();
+       kfree_skb(skb);
 }
 
 /**
        if (link_possible && !fcoe_link_ok(lport))
                fcoe_ctlr_link_up(&fcoe->ctlr);
        else if (fcoe_ctlr_link_down(&fcoe->ctlr)) {
-               stats = fc_lport_get_stats(lport);
+               stats = per_cpu_ptr(lport->dev_stats, get_cpu());
                stats->LinkFailureCount++;
+               put_cpu();
                fcoe_clean_pending_queue(lport);
        }
 out:
 
  * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller
  * @fip: The FCoE controller to free FCFs on
  *
- * Called with lock held.
+ * Called with lock held and preemption disabled.
  *
  * An FCF is considered old if we have missed three advertisements.
  * That is, there have been no valid advertisement from it for three
        struct fcoe_fcf *next;
        unsigned long sel_time = 0;
        unsigned long mda_time = 0;
+       struct fcoe_dev_stats *stats;
 
        list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
                mda_time = fcf->fka_period + (fcf->fka_period >> 1);
                if ((fip->sel_fcf == fcf) &&
                    (time_after(jiffies, fcf->time + mda_time))) {
                        mod_timer(&fip->timer, jiffies + mda_time);
-                       fc_lport_get_stats(fip->lp)->MissDiscAdvCount++;
+                       stats = per_cpu_ptr(fip->lp->dev_stats,
+                                           smp_processor_id());
+                       stats->MissDiscAdvCount++;
                        printk(KERN_INFO "libfcoe: host%d: Missing Discovery "
                               "Advertisement for fab %llx count %lld\n",
                               fip->lp->host->host_no, fcf->fabric_name,
-                              fc_lport_get_stats(fip->lp)->MissDiscAdvCount);
+                              stats->MissDiscAdvCount);
                }
                if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
                               msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
                        WARN_ON(!fip->fcf_count);
                        fip->fcf_count--;
                        kfree(fcf);
-                       fc_lport_get_stats(fip->lp)->VLinkFailureCount++;
+                       stats = per_cpu_ptr(fip->lp->dev_stats,
+                                           smp_processor_id());
+                       stats->VLinkFailureCount++;
                } else if (fcoe_ctlr_mtu_valid(fcf) &&
                           (!sel_time || time_before(sel_time, fcf->time))) {
                        sel_time = fcf->time;
        fr_eof(fp) = FC_EOF_T;
        fr_dev(fp) = lport;
 
-       stats = fc_lport_get_stats(lport);
+       stats = per_cpu_ptr(lport->dev_stats, get_cpu());
        stats->RxFrames++;
        stats->RxWords += skb->len / FIP_BPW;
+       put_cpu();
 
        fc_exch_recv(lport, fp);
        return;
                LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
 
                spin_lock_bh(&fip->lock);
-               fc_lport_get_stats(lport)->VLinkFailureCount++;
+               per_cpu_ptr(lport->dev_stats,
+                           smp_processor_id())->VLinkFailureCount++;
                fcoe_ctlr_reset(fip);
                spin_unlock_bh(&fip->lock);
 
 
        }
        memset(ep, 0, sizeof(*ep));
 
-       cpu = smp_processor_id();
+       cpu = get_cpu();
        pool = per_cpu_ptr(mp->pool, cpu);
        spin_lock_bh(&pool->lock);
+       put_cpu();
        index = pool->next_index;
        /* allocate new exch from pool */
        while (fc_exch_ptr_get(pool, index)) {
 
 
                if (~crc != le32_to_cpu(fr_crc(fp))) {
 crc_err:
-                       stats = fc_lport_get_stats(lport);
+                       stats = per_cpu_ptr(lport->dev_stats, get_cpu());
                        stats->ErrorFrames++;
-                       /* FIXME - per cpu count, not total count! */
+                       /* per cpu count, not total count, but OK for limit */
                        if (stats->InvalidCRCCount++ < 5)
                                printk(KERN_WARNING "libfc: CRC error on data "
                                       "frame for port (%6x)\n",
                                       fc_host_port_id(lport->host));
+                       put_cpu();
                        /*
                         * Assume the frame is total garbage.
                         * We may have copied it over the good part
        /*
         * setup the data direction
         */
-       stats = fc_lport_get_stats(lport);
+       stats = per_cpu_ptr(lport->dev_stats, get_cpu());
        if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
                fsp->req_flags = FC_SRB_READ;
                stats->InputRequests++;
                fsp->req_flags = 0;
                stats->ControlRequests++;
        }
+       put_cpu();
 
        fsp->tgt_flags = rpriv->flags;
 
 
        free_percpu(lport->dev_stats);
 }
 
-/**
- * fc_lport_get_stats() - Get a local port's statistics
- * @lport: The local port whose statistics are to be retreived
- */
-static inline struct fcoe_dev_stats *fc_lport_get_stats(struct fc_lport *lport)
-{
-       return per_cpu_ptr(lport->dev_stats, smp_processor_id());
-}
-
 /**
  * lport_priv() - Return the private data from a local port
  * @lport: The local port whose private data is to be retreived