diff options
author | Bryan O'Sullivan <bos@pathscale.com> | 2007-03-15 17:45:02 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-04-18 23:20:57 -0400 |
commit | 0ed3c594e3878274787810422760dc7c51e0ee72 (patch) | |
tree | a78b2632e23e743ffbfe85e4e235ff2bde77d933 | |
parent | c8c6f5d496fe794cbb52fe5a08c2bd839eecaa07 (diff) |
IB/ipath: Fix calculation for number of kernel PIO buffers
If the module parameter "kpiobufs" is set too high, the calculation to
reset it to a sane value was incorrect.
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_init_chip.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_init_chip.c b/drivers/infiniband/hw/ipath/ipath_init_chip.c index d4f6b5239ef8..1e77b55afe93 100644 --- a/drivers/infiniband/hw/ipath/ipath_init_chip.c +++ b/drivers/infiniband/hw/ipath/ipath_init_chip.c | |||
@@ -668,6 +668,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
668 | { | 668 | { |
669 | int ret = 0, i; | 669 | int ret = 0, i; |
670 | u32 val32, kpiobufs; | 670 | u32 val32, kpiobufs; |
671 | u32 piobufs, uports; | ||
671 | u64 val; | 672 | u64 val; |
672 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ | 673 | struct ipath_portdata *pd = NULL; /* keep gcc4 happy */ |
673 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; | 674 | gfp_t gfp_flags = GFP_USER | __GFP_COMP; |
@@ -702,16 +703,17 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
702 | * the in memory DMA'ed copies of the registers. This has to | 703 | * the in memory DMA'ed copies of the registers. This has to |
703 | * be done early, before we calculate lastport, etc. | 704 | * be done early, before we calculate lastport, etc. |
704 | */ | 705 | */ |
705 | val = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; | 706 | piobufs = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k; |
706 | /* | 707 | /* |
707 | * calc number of pioavail registers, and save it; we have 2 | 708 | * calc number of pioavail registers, and save it; we have 2 |
708 | * bits per buffer. | 709 | * bits per buffer. |
709 | */ | 710 | */ |
710 | dd->ipath_pioavregs = ALIGN(val, sizeof(u64) * BITS_PER_BYTE / 2) | 711 | dd->ipath_pioavregs = ALIGN(piobufs, sizeof(u64) * BITS_PER_BYTE / 2) |
711 | / (sizeof(u64) * BITS_PER_BYTE / 2); | 712 | / (sizeof(u64) * BITS_PER_BYTE / 2); |
713 | uports = dd->ipath_cfgports ? dd->ipath_cfgports - 1 : 0; | ||
712 | if (ipath_kpiobufs == 0) { | 714 | if (ipath_kpiobufs == 0) { |
713 | /* not set by user (this is default) */ | 715 | /* not set by user (this is default) */ |
714 | if ((dd->ipath_piobcnt2k + dd->ipath_piobcnt4k) > 128) | 716 | if (piobufs >= (uports * IPATH_MIN_USER_PORT_BUFCNT) + 32) |
715 | kpiobufs = 32; | 717 | kpiobufs = 32; |
716 | else | 718 | else |
717 | kpiobufs = 16; | 719 | kpiobufs = 16; |
@@ -719,31 +721,25 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
719 | else | 721 | else |
720 | kpiobufs = ipath_kpiobufs; | 722 | kpiobufs = ipath_kpiobufs; |
721 | 723 | ||
722 | if (kpiobufs > | 724 | if (kpiobufs + (uports * IPATH_MIN_USER_PORT_BUFCNT) > piobufs) { |
723 | (dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | 725 | i = (int) piobufs - |
724 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT))) { | 726 | (int) (uports * IPATH_MIN_USER_PORT_BUFCNT); |
725 | i = dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - | ||
726 | (dd->ipath_cfgports * IPATH_MIN_USER_PORT_BUFCNT); | ||
727 | if (i < 0) | 727 | if (i < 0) |
728 | i = 0; | 728 | i = 0; |
729 | dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs for " | 729 | dev_info(&dd->pcidev->dev, "Allocating %d PIO bufs of " |
730 | "kernel leaves too few for %d user ports " | 730 | "%d for kernel leaves too few for %d user ports " |
731 | "(%d each); using %u\n", kpiobufs, | 731 | "(%d each); using %u\n", kpiobufs, |
732 | dd->ipath_cfgports - 1, | 732 | piobufs, uports, IPATH_MIN_USER_PORT_BUFCNT, i); |
733 | IPATH_MIN_USER_PORT_BUFCNT, i); | ||
734 | /* | 733 | /* |
735 | * shouldn't change ipath_kpiobufs, because could be | 734 | * shouldn't change ipath_kpiobufs, because could be |
736 | * different for different devices... | 735 | * different for different devices... |
737 | */ | 736 | */ |
738 | kpiobufs = i; | 737 | kpiobufs = i; |
739 | } | 738 | } |
740 | dd->ipath_lastport_piobuf = | 739 | dd->ipath_lastport_piobuf = piobufs - kpiobufs; |
741 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k - kpiobufs; | 740 | dd->ipath_pbufsport = |
742 | dd->ipath_pbufsport = dd->ipath_cfgports > 1 | 741 | uports ? dd->ipath_lastport_piobuf / uports : 0; |
743 | ? dd->ipath_lastport_piobuf / (dd->ipath_cfgports - 1) | 742 | val32 = dd->ipath_lastport_piobuf - (dd->ipath_pbufsport * uports); |
744 | : 0; | ||
745 | val32 = dd->ipath_lastport_piobuf - | ||
746 | (dd->ipath_pbufsport * (dd->ipath_cfgports - 1)); | ||
747 | if (val32 > 0) { | 743 | if (val32 > 0) { |
748 | ipath_dbg("allocating %u pbufs/port leaves %u unused, " | 744 | ipath_dbg("allocating %u pbufs/port leaves %u unused, " |
749 | "add to kernel\n", dd->ipath_pbufsport, val32); | 745 | "add to kernel\n", dd->ipath_pbufsport, val32); |
@@ -754,8 +750,7 @@ int ipath_init_chip(struct ipath_devdata *dd, int reinit) | |||
754 | dd->ipath_lastpioindex = dd->ipath_lastport_piobuf; | 750 | dd->ipath_lastpioindex = dd->ipath_lastport_piobuf; |
755 | ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " | 751 | ipath_cdbg(VERBOSE, "%d PIO bufs for kernel out of %d total %u " |
756 | "each for %u user ports\n", kpiobufs, | 752 | "each for %u user ports\n", kpiobufs, |
757 | dd->ipath_piobcnt2k + dd->ipath_piobcnt4k, | 753 | piobufs, dd->ipath_pbufsport, uports); |
758 | dd->ipath_pbufsport, dd->ipath_cfgports - 1); | ||
759 | 754 | ||
760 | dd->ipath_f_early_init(dd); | 755 | dd->ipath_f_early_init(dd); |
761 | 756 | ||