aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/nodemgr.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2006-07-02 08:17:00 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2006-09-17 13:17:13 -0400
commit9951903e616662e9a5dad5fbd296690e2ebbbc65 (patch)
tree3d0de40aa9100ccebea03a339dc080f7ad80333e /drivers/ieee1394/nodemgr.c
parent9b4f2e9576658c4e52d95dc8d309f51b2e2db096 (diff)
ieee1394: shrink tlabel pools, remove tpool semaphores
This patch reduces the size of struct hpsb_host and also removes semaphores from ieee1394_transactions.c. On i386, struct hpsb_host shrinks from 10656 bytes to 6688 bytes. This is accomplished by - using a single wait_queue for hpsb_get_tlabel instead of many instances of semaphores, - using a single lock to serialize access to all tlabel pools (the protected code regions are small, i.e. lock contention very low), - omitting the sysfs attribute tlabels_allocations. Drawback: In the rare case that a process needs to sleep because all transaction labels for the node are temporarily exhausted, it is also woken up if a tlabel for a different node became free, checks for an available tlabel, and is put to sleep again. The check is not costly and the situation occurs extremely rarely. (Tlabels are typically only exhausted if there was no context switch to the khpsbpkt thread which recycles tlables.) Therefore the benefit of reduced tpool size outweighs this drawback. The sysfs attributes tlabels_free and tlabels_mask are not compiled anymore unless CONFIG_IEEE1394_VERBOSEDEBUG is set. The by far biggest member of struct hpsb_host, the struct csr_control csr (5272 bytes on i386), is now placed at the end of struct hpsb_host. Note, hpsb_get_tlabel calls the macro wait_event_interruptible with a condition argument which has a side effect (allocation of a tlabel and manipulation of the packet). This side effect happens only if the condition is true. The patch relies on wait_event_interruptible not evaluating the condition again after it became true. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/ieee1394/nodemgr.c')
-rw-r--r--drivers/ieee1394/nodemgr.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index f8f6079cc48c..eabc51b23c0b 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -327,34 +327,44 @@ static ssize_t fw_show_ne_bus_options(struct device *dev, struct device_attribut
327static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL); 327static DEVICE_ATTR(bus_options,S_IRUGO,fw_show_ne_bus_options,NULL);
328 328
329 329
330/* tlabels_free, tlabels_allocations, tlabels_mask are read non-atomically 330#ifdef HPSB_DEBUG_TLABELS
331 * here, therefore displayed values may be occasionally wrong. */ 331static ssize_t fw_show_ne_tlabels_free(struct device *dev,
332static ssize_t fw_show_ne_tlabels_free(struct device *dev, struct device_attribute *attr, char *buf) 332 struct device_attribute *attr, char *buf)
333{ 333{
334 struct node_entry *ne = container_of(dev, struct node_entry, device); 334 struct node_entry *ne = container_of(dev, struct node_entry, device);
335 return sprintf(buf, "%d\n", 64 - bitmap_weight(ne->tpool->pool, 64)); 335 unsigned long flags;
336} 336 unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
337static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL); 337 int tf;
338 338
339 spin_lock_irqsave(&hpsb_tlabel_lock, flags);
340 tf = 64 - bitmap_weight(tp, 64);
341 spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
339 342
340static ssize_t fw_show_ne_tlabels_allocations(struct device *dev, struct device_attribute *attr, char *buf) 343 return sprintf(buf, "%d\n", tf);
341{
342 struct node_entry *ne = container_of(dev, struct node_entry, device);
343 return sprintf(buf, "%u\n", ne->tpool->allocations);
344} 344}
345static DEVICE_ATTR(tlabels_allocations,S_IRUGO,fw_show_ne_tlabels_allocations,NULL); 345static DEVICE_ATTR(tlabels_free,S_IRUGO,fw_show_ne_tlabels_free,NULL);
346 346
347 347
348static ssize_t fw_show_ne_tlabels_mask(struct device *dev, struct device_attribute *attr, char *buf) 348static ssize_t fw_show_ne_tlabels_mask(struct device *dev,
349 struct device_attribute *attr, char *buf)
349{ 350{
350 struct node_entry *ne = container_of(dev, struct node_entry, device); 351 struct node_entry *ne = container_of(dev, struct node_entry, device);
352 unsigned long flags;
353 unsigned long *tp = ne->host->tl_pool[NODEID_TO_NODE(ne->nodeid)].map;
354 u64 tm;
355
356 spin_lock_irqsave(&hpsb_tlabel_lock, flags);
351#if (BITS_PER_LONG <= 32) 357#if (BITS_PER_LONG <= 32)
352 return sprintf(buf, "0x%08lx%08lx\n", ne->tpool->pool[0], ne->tpool->pool[1]); 358 tm = ((u64)tp[0] << 32) + tp[1];
353#else 359#else
354 return sprintf(buf, "0x%016lx\n", ne->tpool->pool[0]); 360 tm = tp[0];
355#endif 361#endif
362 spin_unlock_irqrestore(&hpsb_tlabel_lock, flags);
363
364 return sprintf(buf, "0x%016llx\n", tm);
356} 365}
357static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL); 366static DEVICE_ATTR(tlabels_mask, S_IRUGO, fw_show_ne_tlabels_mask, NULL);
367#endif /* HPSB_DEBUG_TLABELS */
358 368
359 369
360static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 370static ssize_t fw_set_ignore_driver(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
@@ -461,9 +471,10 @@ static struct device_attribute *const fw_ne_attrs[] = {
461 &dev_attr_ne_vendor_id, 471 &dev_attr_ne_vendor_id,
462 &dev_attr_ne_nodeid, 472 &dev_attr_ne_nodeid,
463 &dev_attr_bus_options, 473 &dev_attr_bus_options,
474#ifdef HPSB_DEBUG_TLABELS
464 &dev_attr_tlabels_free, 475 &dev_attr_tlabels_free,
465 &dev_attr_tlabels_allocations,
466 &dev_attr_tlabels_mask, 476 &dev_attr_tlabels_mask,
477#endif
467}; 478};
468 479
469 480
@@ -782,8 +793,6 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
782 if (!ne) 793 if (!ne)
783 return NULL; 794 return NULL;
784 795
785 ne->tpool = &host->tpool[nodeid & NODE_MASK];
786
787 ne->host = host; 796 ne->host = host;
788 ne->nodeid = nodeid; 797 ne->nodeid = nodeid;
789 ne->generation = generation; 798 ne->generation = generation;