diff options
author | simokawa <simokawa@FreeBSD.org> | 2007-07-15 13:00:29 +0000 |
---|---|---|
committer | simokawa <simokawa@FreeBSD.org> | 2007-07-15 13:00:29 +0000 |
commit | 9bdbb066cbe14b1ce7f70c8f6989cd5b9d568543 (patch) | |
tree | 1bd47908e9b3e386865b38283c3830d6240c0d16 /sys/dev/firewire | |
parent | fdb167ed99c6005f2ee4dcefb29495fa599a401e (diff) | |
download | FreeBSD-src-9bdbb066cbe14b1ce7f70c8f6989cd5b9d568543.zip FreeBSD-src-9bdbb066cbe14b1ce7f70c8f6989cd5b9d568543.tar.gz |
Improve acquisition of transaction labels.
- Keep last transaction label for each destination.
- If the next label is not free, just give up.
- This should reduce CPU load for TX on if_fwip under heavy load.
Approved by: re (hrs)
Diffstat (limited to 'sys/dev/firewire')
-rw-r--r-- | sys/dev/firewire/firewire.c | 36 | ||||
-rw-r--r-- | sys/dev/firewire/firewirereg.h | 1 |
2 files changed, 17 insertions, 20 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index 4015d56..9421b62 100644 --- a/sys/dev/firewire/firewire.c +++ b/sys/dev/firewire/firewire.c @@ -1711,38 +1711,34 @@ fw_attach_dev(struct firewire_comm *fc) static int fw_get_tlabel(struct firewire_comm *fc, struct fw_xfer *xfer) { - u_int i; + u_int dst, new_tlabel; struct fw_xfer *txfer; int s; - static uint32_t label = 0; + dst = xfer->send.hdr.mode.hdr.dst & 0x3f; s = splfw(); FW_GLOCK(fc); - for( i = 0 ; i < 0x40 ; i ++){ - label = (label + 1) & 0x3f; - STAILQ_FOREACH(txfer, &fc->tlabels[label], tlabel) - if (txfer->send.hdr.mode.hdr.dst == - xfer->send.hdr.mode.hdr.dst) + new_tlabel = (fc->last_tlabel[dst] + 1) & 0x3f; + STAILQ_FOREACH(txfer, &fc->tlabels[new_tlabel], tlabel) + if ((txfer->send.hdr.mode.hdr.dst & 0x3f) == dst) break; - if(txfer == NULL) { - xfer->tl = label; - xfer->send.hdr.mode.hdr.tlrt = label << 2; - STAILQ_INSERT_TAIL(&fc->tlabels[label], xfer, tlabel); - FW_GUNLOCK(fc); - splx(s); - if (firewire_debug > 1) - printf("fw_get_tlabel: dst=%d tl=%d\n", - xfer->send.hdr.mode.hdr.dst, label); - /* note: label may be incremanted after unlock */ - return(xfer->tl); - } + if(txfer == NULL) { + fc->last_tlabel[dst] = new_tlabel; + STAILQ_INSERT_TAIL(&fc->tlabels[new_tlabel], xfer, tlabel); + FW_GUNLOCK(fc); + splx(s); + xfer->tl = new_tlabel; + xfer->send.hdr.mode.hdr.tlrt = new_tlabel << 2; + if (firewire_debug > 1) + printf("fw_get_tlabel: dst=%d tl=%d\n", dst, new_tlabel); + return (new_tlabel); } FW_GUNLOCK(fc); splx(s); if (firewire_debug > 1) printf("fw_get_tlabel: no free tlabel\n"); - return(-1); + return (-1); } static void diff --git a/sys/dev/firewire/firewirereg.h b/sys/dev/firewire/firewirereg.h index d2d9d65..0ceb5a2 100644 --- a/sys/dev/firewire/firewirereg.h +++ b/sys/dev/firewire/firewirereg.h @@ -133,6 +133,7 @@ struct firewire_comm{ struct fw_xferq *arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH]; struct fw_xferlist tlabels[0x40]; + u_char last_tlabel[0x40]; STAILQ_HEAD(, fw_bind) binds; STAILQ_HEAD(, fw_device) devices; u_int sid_cnt; |