diff options
author | Vasu Dev <vasu.dev@intel.com> | 2009-05-06 13:52:40 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-06-08 14:29:14 -0400 |
commit | 1047f22108bd9bfedefd3ff014cb56691dfbaa3f (patch) | |
tree | 1c651877a07e81d9be009dfe5cd95fc2b127584c /drivers/scsi | |
parent | 4bb6b5153313269b4b328f4f5ddc558c45c50713 (diff) |
[SCSI] fcoe: removes fcoe_watchdog
Removes periodic fcoe_watchdog timer used across all fcoe interface
maintained in fcoe_hostlist instead added new fcoe_queue_timer
per fcoe interface.
Added timer is armed only when some pending skb need to be flushed
as oppose to periodic 1 second fcoe_watchdog, since now
fcoe_queue_timer is used on demand thus set this to 2 jiffies.
Now fcoe_queue_timer is much simple than fcoe_watchdog using lock to
process all fcoe interface from fcoe_hostlist.
I noticed +ve performance result with using 2 jiffies timer as
this helps flushing fcoe_pending_queue quickly.
Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 52 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 1 |
2 files changed, 19 insertions, 34 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 30eba75a5cd..6e7a700f5d5 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -54,7 +54,6 @@ MODULE_LICENSE("GPL v2"); | |||
54 | /* fcoe host list */ | 54 | /* fcoe host list */ |
55 | LIST_HEAD(fcoe_hostlist); | 55 | LIST_HEAD(fcoe_hostlist); |
56 | DEFINE_RWLOCK(fcoe_hostlist_lock); | 56 | DEFINE_RWLOCK(fcoe_hostlist_lock); |
57 | DEFINE_TIMER(fcoe_timer, NULL, 0, 0); | ||
58 | DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); | 57 | DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu); |
59 | 58 | ||
60 | /* Function Prototypes */ | 59 | /* Function Prototypes */ |
@@ -168,6 +167,18 @@ static int fcoe_lport_config(struct fc_lport *lp) | |||
168 | } | 167 | } |
169 | 168 | ||
170 | /** | 169 | /** |
170 | * fcoe_queue_timer() - fcoe queue timer | ||
171 | * @lp: the fc_lport pointer | ||
172 | * | ||
173 | * Calls fcoe_check_wait_queue on timeout | ||
174 | * | ||
175 | */ | ||
176 | static void fcoe_queue_timer(ulong lp) | ||
177 | { | ||
178 | fcoe_check_wait_queue((struct fc_lport *)lp, NULL); | ||
179 | } | ||
180 | |||
181 | /** | ||
171 | * fcoe_netdev_config() - Set up netdev for SW FCoE | 182 | * fcoe_netdev_config() - Set up netdev for SW FCoE |
172 | * @lp : ptr to the fc_lport | 183 | * @lp : ptr to the fc_lport |
173 | * @netdev : ptr to the associated netdevice struct | 184 | * @netdev : ptr to the associated netdevice struct |
@@ -237,6 +248,7 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev) | |||
237 | } | 248 | } |
238 | skb_queue_head_init(&fc->fcoe_pending_queue); | 249 | skb_queue_head_init(&fc->fcoe_pending_queue); |
239 | fc->fcoe_pending_queue_active = 0; | 250 | fc->fcoe_pending_queue_active = 0; |
251 | setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp); | ||
240 | 252 | ||
241 | /* setup Source Mac Address */ | 253 | /* setup Source Mac Address */ |
242 | memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr, | 254 | memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr, |
@@ -387,6 +399,9 @@ static int fcoe_if_destroy(struct net_device *netdev) | |||
387 | /* Free existing skbs */ | 399 | /* Free existing skbs */ |
388 | fcoe_clean_pending_queue(lp); | 400 | fcoe_clean_pending_queue(lp); |
389 | 401 | ||
402 | /* Stop the timer */ | ||
403 | del_timer_sync(&fc->timer); | ||
404 | |||
390 | /* Free memory used by statistical counters */ | 405 | /* Free memory used by statistical counters */ |
391 | fc_lport_free_stats(lp); | 406 | fc_lport_free_stats(lp); |
392 | 407 | ||
@@ -1260,32 +1275,6 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1260 | } | 1275 | } |
1261 | 1276 | ||
1262 | /** | 1277 | /** |
1263 | * fcoe_watchdog() - fcoe timer callback | ||
1264 | * @vp: | ||
1265 | * | ||
1266 | * This checks the pending queue length for fcoe and set lport qfull | ||
1267 | * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the | ||
1268 | * fcoe_hostlist. | ||
1269 | * | ||
1270 | * Returns: 0 for success | ||
1271 | */ | ||
1272 | void fcoe_watchdog(ulong vp) | ||
1273 | { | ||
1274 | struct fcoe_softc *fc; | ||
1275 | |||
1276 | read_lock(&fcoe_hostlist_lock); | ||
1277 | list_for_each_entry(fc, &fcoe_hostlist, list) { | ||
1278 | if (fc->ctlr.lp) | ||
1279 | fcoe_check_wait_queue(fc->ctlr.lp, NULL); | ||
1280 | } | ||
1281 | read_unlock(&fcoe_hostlist_lock); | ||
1282 | |||
1283 | fcoe_timer.expires = jiffies + (1 * HZ); | ||
1284 | add_timer(&fcoe_timer); | ||
1285 | } | ||
1286 | |||
1287 | |||
1288 | /** | ||
1289 | * fcoe_check_wait_queue() - attempt to clear the transmit backlog | 1278 | * fcoe_check_wait_queue() - attempt to clear the transmit backlog |
1290 | * @lp: the fc_lport | 1279 | * @lp: the fc_lport |
1291 | * | 1280 | * |
@@ -1333,6 +1322,8 @@ static void fcoe_check_wait_queue(struct fc_lport *lp, struct sk_buff *skb) | |||
1333 | 1322 | ||
1334 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) | 1323 | if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH) |
1335 | lp->qfull = 0; | 1324 | lp->qfull = 0; |
1325 | if (fc->fcoe_pending_queue.qlen && !timer_pending(&fc->timer)) | ||
1326 | mod_timer(&fc->timer, jiffies + 2); | ||
1336 | fc->fcoe_pending_queue_active = 0; | 1327 | fc->fcoe_pending_queue_active = 0; |
1337 | out: | 1328 | out: |
1338 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) | 1329 | if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH) |
@@ -1809,10 +1800,6 @@ static int __init fcoe_init(void) | |||
1809 | /* Setup link change notification */ | 1800 | /* Setup link change notification */ |
1810 | fcoe_dev_setup(); | 1801 | fcoe_dev_setup(); |
1811 | 1802 | ||
1812 | setup_timer(&fcoe_timer, fcoe_watchdog, 0); | ||
1813 | |||
1814 | mod_timer(&fcoe_timer, jiffies + (10 * HZ)); | ||
1815 | |||
1816 | fcoe_if_init(); | 1803 | fcoe_if_init(); |
1817 | 1804 | ||
1818 | return 0; | 1805 | return 0; |
@@ -1838,9 +1825,6 @@ static void __exit fcoe_exit(void) | |||
1838 | 1825 | ||
1839 | fcoe_dev_cleanup(); | 1826 | fcoe_dev_cleanup(); |
1840 | 1827 | ||
1841 | /* Stop the timer */ | ||
1842 | del_timer_sync(&fcoe_timer); | ||
1843 | |||
1844 | /* releases the associated fcoe hosts */ | 1828 | /* releases the associated fcoe hosts */ |
1845 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) | 1829 | list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) |
1846 | fcoe_if_destroy(fc->real_dev); | 1830 | fcoe_if_destroy(fc->real_dev); |
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index 917aae88689..a1eb8c1988b 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h | |||
@@ -61,6 +61,7 @@ struct fcoe_softc { | |||
61 | struct packet_type fip_packet_type; | 61 | struct packet_type fip_packet_type; |
62 | struct sk_buff_head fcoe_pending_queue; | 62 | struct sk_buff_head fcoe_pending_queue; |
63 | u8 fcoe_pending_queue_active; | 63 | u8 fcoe_pending_queue_active; |
64 | struct timer_list timer; /* queue timer */ | ||
64 | struct fcoe_ctlr ctlr; | 65 | struct fcoe_ctlr ctlr; |
65 | }; | 66 | }; |
66 | 67 | ||