aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorRobert Love <robert.w.love@intel.com>2009-03-31 18:51:50 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:22:58 -0400
commit582b45bc577f78b5bfff3db874594ce2d962b846 (patch)
treeb0cfe95b235aeca9b967cba8446db58b8a102533 /drivers/scsi
parent5e5e92df49d4dfbef9ba981297c7f76d189376ac (diff)
[SCSI] fcoe: Use per-CPU kernel function for dev_stats instead of an array
Remove the hotplug creation of dev_stats, we allocate for all possible CPUs now when we allocate the lport. v2: Durring the 2.6.30 merge window, before these patches were comitted, 'percpu_ptr' was renamed 'per_cpu_ptr'. This latest update updates this patch for the name change. Signed-off-by: Yi Zou <yi.zou@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/fcoe/fcoe_sw.c13
-rw-r--r--drivers/scsi/fcoe/libfcoe.c143
-rw-r--r--drivers/scsi/libfc/fc_fcp.c8
-rw-r--r--drivers/scsi/libfc/fc_lport.c11
4 files changed, 31 insertions, 144 deletions
diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
index 2bbbe3c0cc7b..a6753903fd40 100644
--- a/drivers/scsi/fcoe/fcoe_sw.c
+++ b/drivers/scsi/fcoe/fcoe_sw.c
@@ -113,8 +113,6 @@ static struct scsi_host_template fcoe_sw_shost_template = {
113 */ 113 */
114static int fcoe_sw_lport_config(struct fc_lport *lp) 114static int fcoe_sw_lport_config(struct fc_lport *lp)
115{ 115{
116 int i = 0;
117
118 lp->link_up = 0; 116 lp->link_up = 0;
119 lp->qfull = 0; 117 lp->qfull = 0;
120 lp->max_retry_count = 3; 118 lp->max_retry_count = 3;
@@ -123,12 +121,7 @@ static int fcoe_sw_lport_config(struct fc_lport *lp)
123 lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS | 121 lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
124 FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL); 122 FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
125 123
126 /* 124 fc_lport_init_stats(lp);
127 * allocate per cpu stats block
128 */
129 for_each_online_cpu(i)
130 lp->dev_stats[i] = kzalloc(sizeof(struct fcoe_dev_stats),
131 GFP_KERNEL);
132 125
133 /* lport fc_lport related configuration */ 126 /* lport fc_lport related configuration */
134 fc_lport_config(lp); 127 fc_lport_config(lp);
@@ -311,7 +304,6 @@ static inline int fcoe_sw_em_config(struct fc_lport *lp)
311 */ 304 */
312static int fcoe_sw_destroy(struct net_device *netdev) 305static int fcoe_sw_destroy(struct net_device *netdev)
313{ 306{
314 int cpu;
315 struct fc_lport *lp = NULL; 307 struct fc_lport *lp = NULL;
316 struct fcoe_softc *fc; 308 struct fcoe_softc *fc;
317 u8 flogi_maddr[ETH_ALEN]; 309 u8 flogi_maddr[ETH_ALEN];
@@ -363,8 +355,7 @@ static int fcoe_sw_destroy(struct net_device *netdev)
363 fcoe_clean_pending_queue(lp); 355 fcoe_clean_pending_queue(lp);
364 356
365 /* Free memory used by statistical counters */ 357 /* Free memory used by statistical counters */
366 for_each_online_cpu(cpu) 358 fc_lport_free_stats(lp);
367 kfree(lp->dev_stats[cpu]);
368 359
369 /* Release the net_device and Scsi_Host */ 360 /* Release the net_device and Scsi_Host */
370 dev_put(fc->real_dev); 361 dev_put(fc->real_dev);
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index d22275bf57f8..648a2fc04271 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -71,9 +71,6 @@ DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
71/* Function Prototyes */ 71/* Function Prototyes */
72static int fcoe_check_wait_queue(struct fc_lport *); 72static int fcoe_check_wait_queue(struct fc_lport *);
73static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *); 73static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
74#ifdef CONFIG_HOTPLUG_CPU
75static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
76#endif /* CONFIG_HOTPLUG_CPU */
77static int fcoe_device_notification(struct notifier_block *, ulong, void *); 74static int fcoe_device_notification(struct notifier_block *, ulong, void *);
78static void fcoe_dev_setup(void); 75static void fcoe_dev_setup(void);
79static void fcoe_dev_cleanup(void); 76static void fcoe_dev_cleanup(void);
@@ -83,87 +80,6 @@ static struct notifier_block fcoe_notifier = {
83 .notifier_call = fcoe_device_notification, 80 .notifier_call = fcoe_device_notification,
84}; 81};
85 82
86
87#ifdef CONFIG_HOTPLUG_CPU
88static struct notifier_block fcoe_cpu_notifier = {
89 .notifier_call = fcoe_cpu_callback,
90};
91
92/**
93 * fcoe_create_percpu_data() - creates the associated cpu data
94 * @cpu: index for the cpu where fcoe cpu data will be created
95 *
96 * create percpu stats block, from cpu add notifier
97 *
98 * Returns: none
99 */
100static void fcoe_create_percpu_data(unsigned int cpu)
101{
102 struct fc_lport *lp;
103 struct fcoe_softc *fc;
104
105 write_lock_bh(&fcoe_hostlist_lock);
106 list_for_each_entry(fc, &fcoe_hostlist, list) {
107 lp = fc->lp;
108 if (lp->dev_stats[cpu] == NULL)
109 lp->dev_stats[cpu] =
110 kzalloc(sizeof(struct fcoe_dev_stats),
111 GFP_KERNEL);
112 }
113 write_unlock_bh(&fcoe_hostlist_lock);
114}
115
116/**
117 * fcoe_destroy_percpu_data() - destroys the associated cpu data
118 * @cpu: index for the cpu where fcoe cpu data will destroyed
119 *
120 * destroy percpu stats block called by cpu add/remove notifier
121 *
122 * Retuns: none
123 */
124static void fcoe_destroy_percpu_data(unsigned int cpu)
125{
126 struct fc_lport *lp;
127 struct fcoe_softc *fc;
128
129 write_lock_bh(&fcoe_hostlist_lock);
130 list_for_each_entry(fc, &fcoe_hostlist, list) {
131 lp = fc->lp;
132 kfree(lp->dev_stats[cpu]);
133 lp->dev_stats[cpu] = NULL;
134 }
135 write_unlock_bh(&fcoe_hostlist_lock);
136}
137
138/**
139 * fcoe_cpu_callback() - fcoe cpu hotplug event callback
140 * @nfb: callback data block
141 * @action: event triggering the callback
142 * @hcpu: index for the cpu of this event
143 *
144 * this creates or destroys per cpu data for fcoe
145 *
146 * Returns NOTIFY_OK always.
147 */
148static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
149 void *hcpu)
150{
151 unsigned int cpu = (unsigned long)hcpu;
152
153 switch (action) {
154 case CPU_ONLINE:
155 fcoe_create_percpu_data(cpu);
156 break;
157 case CPU_DEAD:
158 fcoe_destroy_percpu_data(cpu);
159 break;
160 default:
161 break;
162 }
163 return NOTIFY_OK;
164}
165#endif /* CONFIG_HOTPLUG_CPU */
166
167/** 83/**
168 * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ 84 * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
169 * @skb: the receive skb 85 * @skb: the receive skb
@@ -181,7 +97,6 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
181 struct fc_lport *lp; 97 struct fc_lport *lp;
182 struct fcoe_rcv_info *fr; 98 struct fcoe_rcv_info *fr;
183 struct fcoe_softc *fc; 99 struct fcoe_softc *fc;
184 struct fcoe_dev_stats *stats;
185 struct fc_frame_header *fh; 100 struct fc_frame_header *fh;
186 struct fcoe_percpu_s *fps; 101 struct fcoe_percpu_s *fps;
187 unsigned short oxid; 102 unsigned short oxid;
@@ -252,13 +167,7 @@ int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
252 167
253 return 0; 168 return 0;
254err: 169err:
255#ifdef CONFIG_SMP 170 fc_lport_get_stats(lp)->ErrorFrames++;
256 stats = lp->dev_stats[smp_processor_id()];
257#else
258 stats = lp->dev_stats[0];
259#endif
260 if (stats)
261 stats->ErrorFrames++;
262 171
263err2: 172err2:
264 kfree_skb(skb); 173 kfree_skb(skb);
@@ -495,11 +404,9 @@ int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
495 } 404 }
496#endif 405#endif
497 /* update tx stats: regardless if LLD fails */ 406 /* update tx stats: regardless if LLD fails */
498 stats = lp->dev_stats[smp_processor_id()]; 407 stats = fc_lport_get_stats(lp);
499 if (stats) { 408 stats->TxFrames++;
500 stats->TxFrames++; 409 stats->TxWords += wlen;
501 stats->TxWords += wlen;
502 }
503 410
504 /* send down to lld */ 411 /* send down to lld */
505 fr_dev(fp) = lp; 412 fr_dev(fp) = lp;
@@ -565,8 +472,6 @@ int fcoe_percpu_receive_thread(void *arg)
565 continue; 472 continue;
566 } 473 }
567 474
568 stats = lp->dev_stats[smp_processor_id()];
569
570 if (unlikely(debug_fcoe)) { 475 if (unlikely(debug_fcoe)) {
571 FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p " 476 FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
572 "tail:%p end:%p sum:%d dev:%s", 477 "tail:%p end:%p sum:%d dev:%s",
@@ -593,13 +498,16 @@ int fcoe_percpu_receive_thread(void *arg)
593 hp = (struct fcoe_hdr *) skb_network_header(skb); 498 hp = (struct fcoe_hdr *) skb_network_header(skb);
594 fh = (struct fc_frame_header *) skb_transport_header(skb); 499 fh = (struct fc_frame_header *) skb_transport_header(skb);
595 500
501 stats = fc_lport_get_stats(lp);
596 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) { 502 if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
597 if (stats) { 503 if (stats->ErrorFrames < 5)
598 if (stats->ErrorFrames < 5) 504 printk(KERN_WARNING "FCoE version "
599 FC_DBG("unknown FCoE version %x", 505 "mismatch: The frame has "
600 FC_FCOE_DECAPS_VER(hp)); 506 "version %x, but the "
601 stats->ErrorFrames++; 507 "initiator supports version "
602 } 508 "%x\n", FC_FCOE_DECAPS_VER(hp),
509 FC_FCOE_VER);
510 stats->ErrorFrames++;
603 kfree_skb(skb); 511 kfree_skb(skb);
604 continue; 512 continue;
605 } 513 }
@@ -607,10 +515,8 @@ int fcoe_percpu_receive_thread(void *arg)
607 skb_pull(skb, sizeof(struct fcoe_hdr)); 515 skb_pull(skb, sizeof(struct fcoe_hdr));
608 fr_len = skb->len - sizeof(struct fcoe_crc_eof); 516 fr_len = skb->len - sizeof(struct fcoe_crc_eof);
609 517
610 if (stats) { 518 stats->RxFrames++;
611 stats->RxFrames++; 519 stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
612 stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
613 }
614 520
615 fp = (struct fc_frame *)skb; 521 fp = (struct fc_frame *)skb;
616 fc_frame_init(fp); 522 fc_frame_init(fp);
@@ -885,9 +791,8 @@ static int fcoe_device_notification(struct notifier_block *notifier,
885 if (new_link_up) 791 if (new_link_up)
886 fc_linkup(lp); 792 fc_linkup(lp);
887 else { 793 else {
888 stats = lp->dev_stats[smp_processor_id()]; 794 stats = fc_lport_get_stats(lp);
889 if (stats) 795 stats->LinkFailureCount++;
890 stats->LinkFailureCount++;
891 fc_linkdown(lp); 796 fc_linkdown(lp);
892 fcoe_clean_pending_queue(lp); 797 fcoe_clean_pending_queue(lp);
893 } 798 }
@@ -1371,10 +1276,6 @@ static int __init fcoe_init(void)
1371 INIT_LIST_HEAD(&fcoe_hostlist); 1276 INIT_LIST_HEAD(&fcoe_hostlist);
1372 rwlock_init(&fcoe_hostlist_lock); 1277 rwlock_init(&fcoe_hostlist_lock);
1373 1278
1374#ifdef CONFIG_HOTPLUG_CPU
1375 register_cpu_notifier(&fcoe_cpu_notifier);
1376#endif /* CONFIG_HOTPLUG_CPU */
1377
1378 for_each_possible_cpu(cpu) { 1279 for_each_possible_cpu(cpu) {
1379 p = &per_cpu(fcoe_percpu, cpu); 1280 p = &per_cpu(fcoe_percpu, cpu);
1380 skb_queue_head_init(&p->fcoe_rx_list); 1281 skb_queue_head_init(&p->fcoe_rx_list);
@@ -1430,17 +1331,9 @@ static void __exit fcoe_exit(void)
1430 struct fcoe_percpu_s *p; 1331 struct fcoe_percpu_s *p;
1431 struct sk_buff *skb; 1332 struct sk_buff *skb;
1432 1333
1433 /*
1434 * Stop all call back interfaces
1435 */
1436#ifdef CONFIG_HOTPLUG_CPU
1437 unregister_cpu_notifier(&fcoe_cpu_notifier);
1438#endif /* CONFIG_HOTPLUG_CPU */
1439 fcoe_dev_cleanup(); 1334 fcoe_dev_cleanup();
1440 1335
1441 /* 1336 /* Stop the timer */
1442 * stop timer
1443 */
1444 del_timer_sync(&fcoe_timer); 1337 del_timer_sync(&fcoe_timer);
1445 1338
1446 /* releases the associated fcoe transport for each lport */ 1339 /* releases the associated fcoe transport for each lport */
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index a5725f3b7ce1..0997e8b1dcea 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -407,10 +407,12 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
407 407
408 if (~crc != le32_to_cpu(fr_crc(fp))) { 408 if (~crc != le32_to_cpu(fr_crc(fp))) {
409crc_err: 409crc_err:
410 stats = lp->dev_stats[smp_processor_id()]; 410 stats = fc_lport_get_stats(lp);
411 stats->ErrorFrames++; 411 stats->ErrorFrames++;
412 /* FIXME - per cpu count, not total count! */
412 if (stats->InvalidCRCCount++ < 5) 413 if (stats->InvalidCRCCount++ < 5)
413 FC_DBG("CRC error on data frame\n"); 414 printk(KERN_WARNING "CRC error on data frame for port (%6x)\n",
415 fc_host_port_id(lp->host));
414 /* 416 /*
415 * Assume the frame is total garbage. 417 * Assume the frame is total garbage.
416 * We may have copied it over the good part 418 * We may have copied it over the good part
@@ -1752,7 +1754,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
1752 /* 1754 /*
1753 * setup the data direction 1755 * setup the data direction
1754 */ 1756 */
1755 stats = lp->dev_stats[smp_processor_id()]; 1757 stats = fc_lport_get_stats(lp);
1756 if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { 1758 if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
1757 fsp->req_flags = FC_SRB_READ; 1759 fsp->req_flags = FC_SRB_READ;
1758 stats->InputRequests++; 1760 stats->InputRequests++;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 7ef44501ecc6..b8178ef398d7 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -267,10 +267,10 @@ EXPORT_SYMBOL(fc_get_host_speed);
267 267
268struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost) 268struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
269{ 269{
270 int i;
271 struct fc_host_statistics *fcoe_stats; 270 struct fc_host_statistics *fcoe_stats;
272 struct fc_lport *lp = shost_priv(shost); 271 struct fc_lport *lp = shost_priv(shost);
273 struct timespec v0, v1; 272 struct timespec v0, v1;
273 unsigned int cpu;
274 274
275 fcoe_stats = &lp->host_stats; 275 fcoe_stats = &lp->host_stats;
276 memset(fcoe_stats, 0, sizeof(struct fc_host_statistics)); 276 memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
@@ -279,10 +279,11 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
279 jiffies_to_timespec(lp->boot_time, &v1); 279 jiffies_to_timespec(lp->boot_time, &v1);
280 fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec); 280 fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
281 281
282 for_each_online_cpu(i) { 282 for_each_possible_cpu(cpu) {
283 struct fcoe_dev_stats *stats = lp->dev_stats[i]; 283 struct fcoe_dev_stats *stats;
284 if (stats == NULL) 284
285 continue; 285 stats = per_cpu_ptr(lp->dev_stats, cpu);
286
286 fcoe_stats->tx_frames += stats->TxFrames; 287 fcoe_stats->tx_frames += stats->TxFrames;
287 fcoe_stats->tx_words += stats->TxWords; 288 fcoe_stats->tx_words += stats->TxWords;
288 fcoe_stats->rx_frames += stats->RxFrames; 289 fcoe_stats->rx_frames += stats->RxFrames;