diff options
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_file_ops.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_file_ops.c | 91 |
1 files changed, 41 insertions, 50 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c index 8b1752202e78..b472b15637f0 100644 --- a/drivers/infiniband/hw/ipath/ipath_file_ops.c +++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c | |||
@@ -173,47 +173,25 @@ static int ipath_get_base_info(struct file *fp, | |||
173 | (void *) dd->ipath_statusp - | 173 | (void *) dd->ipath_statusp - |
174 | (void *) dd->ipath_pioavailregs_dma; | 174 | (void *) dd->ipath_pioavailregs_dma; |
175 | if (!shared) { | 175 | if (!shared) { |
176 | kinfo->spi_piocnt = dd->ipath_pbufsport; | 176 | kinfo->spi_piocnt = pd->port_piocnt; |
177 | kinfo->spi_piobufbase = (u64) pd->port_piobufs; | 177 | kinfo->spi_piobufbase = (u64) pd->port_piobufs; |
178 | kinfo->__spi_uregbase = (u64) dd->ipath_uregbase + | 178 | kinfo->__spi_uregbase = (u64) dd->ipath_uregbase + |
179 | dd->ipath_ureg_align * pd->port_port; | 179 | dd->ipath_ureg_align * pd->port_port; |
180 | } else if (master) { | 180 | } else if (master) { |
181 | kinfo->spi_piocnt = (dd->ipath_pbufsport / subport_cnt) + | 181 | kinfo->spi_piocnt = (pd->port_piocnt / subport_cnt) + |
182 | (dd->ipath_pbufsport % subport_cnt); | 182 | (pd->port_piocnt % subport_cnt); |
183 | /* Master's PIO buffers are after all the slave's */ | 183 | /* Master's PIO buffers are after all the slave's */ |
184 | kinfo->spi_piobufbase = (u64) pd->port_piobufs + | 184 | kinfo->spi_piobufbase = (u64) pd->port_piobufs + |
185 | dd->ipath_palign * | 185 | dd->ipath_palign * |
186 | (dd->ipath_pbufsport - kinfo->spi_piocnt); | 186 | (pd->port_piocnt - kinfo->spi_piocnt); |
187 | } else { | 187 | } else { |
188 | unsigned slave = subport_fp(fp) - 1; | 188 | unsigned slave = subport_fp(fp) - 1; |
189 | 189 | ||
190 | kinfo->spi_piocnt = dd->ipath_pbufsport / subport_cnt; | 190 | kinfo->spi_piocnt = pd->port_piocnt / subport_cnt; |
191 | kinfo->spi_piobufbase = (u64) pd->port_piobufs + | 191 | kinfo->spi_piobufbase = (u64) pd->port_piobufs + |
192 | dd->ipath_palign * kinfo->spi_piocnt * slave; | 192 | dd->ipath_palign * kinfo->spi_piocnt * slave; |
193 | } | 193 | } |
194 | 194 | ||
195 | /* | ||
196 | * Set the PIO avail update threshold to no larger | ||
197 | * than the number of buffers per process. Note that | ||
198 | * we decrease it here, but won't ever increase it. | ||
199 | */ | ||
200 | if (dd->ipath_pioupd_thresh && | ||
201 | kinfo->spi_piocnt < dd->ipath_pioupd_thresh) { | ||
202 | unsigned long flags; | ||
203 | |||
204 | dd->ipath_pioupd_thresh = kinfo->spi_piocnt; | ||
205 | ipath_dbg("Decreased pio update threshold to %u\n", | ||
206 | dd->ipath_pioupd_thresh); | ||
207 | spin_lock_irqsave(&dd->ipath_sendctrl_lock, flags); | ||
208 | dd->ipath_sendctrl &= ~(INFINIPATH_S_UPDTHRESH_MASK | ||
209 | << INFINIPATH_S_UPDTHRESH_SHIFT); | ||
210 | dd->ipath_sendctrl |= dd->ipath_pioupd_thresh | ||
211 | << INFINIPATH_S_UPDTHRESH_SHIFT; | ||
212 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
213 | dd->ipath_sendctrl); | ||
214 | spin_unlock_irqrestore(&dd->ipath_sendctrl_lock, flags); | ||
215 | } | ||
216 | |||
217 | if (shared) { | 195 | if (shared) { |
218 | kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase + | 196 | kinfo->spi_port_uregbase = (u64) dd->ipath_uregbase + |
219 | dd->ipath_ureg_align * pd->port_port; | 197 | dd->ipath_ureg_align * pd->port_port; |
@@ -577,7 +555,7 @@ static int ipath_tid_free(struct ipath_portdata *pd, unsigned subport, | |||
577 | p = dd->ipath_pageshadow[porttid + tid]; | 555 | p = dd->ipath_pageshadow[porttid + tid]; |
578 | dd->ipath_pageshadow[porttid + tid] = NULL; | 556 | dd->ipath_pageshadow[porttid + tid] = NULL; |
579 | ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", | 557 | ipath_cdbg(VERBOSE, "PID %u freeing TID %u\n", |
580 | pd->port_pid, tid); | 558 | pid_nr(pd->port_pid), tid); |
581 | dd->ipath_f_put_tid(dd, &tidbase[tid], | 559 | dd->ipath_f_put_tid(dd, &tidbase[tid], |
582 | RCVHQ_RCV_TYPE_EXPECTED, | 560 | RCVHQ_RCV_TYPE_EXPECTED, |
583 | dd->ipath_tidinvalid); | 561 | dd->ipath_tidinvalid); |
@@ -1309,19 +1287,19 @@ static int ipath_mmap(struct file *fp, struct vm_area_struct *vma) | |||
1309 | ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; | 1287 | ureg = dd->ipath_uregbase + dd->ipath_ureg_align * pd->port_port; |
1310 | if (!pd->port_subport_cnt) { | 1288 | if (!pd->port_subport_cnt) { |
1311 | /* port is not shared */ | 1289 | /* port is not shared */ |
1312 | piocnt = dd->ipath_pbufsport; | 1290 | piocnt = pd->port_piocnt; |
1313 | piobufs = pd->port_piobufs; | 1291 | piobufs = pd->port_piobufs; |
1314 | } else if (!subport_fp(fp)) { | 1292 | } else if (!subport_fp(fp)) { |
1315 | /* caller is the master */ | 1293 | /* caller is the master */ |
1316 | piocnt = (dd->ipath_pbufsport / pd->port_subport_cnt) + | 1294 | piocnt = (pd->port_piocnt / pd->port_subport_cnt) + |
1317 | (dd->ipath_pbufsport % pd->port_subport_cnt); | 1295 | (pd->port_piocnt % pd->port_subport_cnt); |
1318 | piobufs = pd->port_piobufs + | 1296 | piobufs = pd->port_piobufs + |
1319 | dd->ipath_palign * (dd->ipath_pbufsport - piocnt); | 1297 | dd->ipath_palign * (pd->port_piocnt - piocnt); |
1320 | } else { | 1298 | } else { |
1321 | unsigned slave = subport_fp(fp) - 1; | 1299 | unsigned slave = subport_fp(fp) - 1; |
1322 | 1300 | ||
1323 | /* caller is a slave */ | 1301 | /* caller is a slave */ |
1324 | piocnt = dd->ipath_pbufsport / pd->port_subport_cnt; | 1302 | piocnt = pd->port_piocnt / pd->port_subport_cnt; |
1325 | piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave; | 1303 | piobufs = pd->port_piobufs + dd->ipath_palign * piocnt * slave; |
1326 | } | 1304 | } |
1327 | 1305 | ||
@@ -1631,11 +1609,8 @@ static int try_alloc_port(struct ipath_devdata *dd, int port, | |||
1631 | port); | 1609 | port); |
1632 | pd->port_cnt = 1; | 1610 | pd->port_cnt = 1; |
1633 | port_fp(fp) = pd; | 1611 | port_fp(fp) = pd; |
1634 | pd->port_pid = current->pid; | 1612 | pd->port_pid = get_pid(task_pid(current)); |
1635 | strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm)); | 1613 | strncpy(pd->port_comm, current->comm, sizeof(pd->port_comm)); |
1636 | ipath_chg_pioavailkernel(dd, | ||
1637 | dd->ipath_pbufsport * (pd->port_port - 1), | ||
1638 | dd->ipath_pbufsport, 0); | ||
1639 | ipath_stats.sps_ports++; | 1614 | ipath_stats.sps_ports++; |
1640 | ret = 0; | 1615 | ret = 0; |
1641 | } else | 1616 | } else |
@@ -1818,14 +1793,15 @@ static int find_shared_port(struct file *fp, | |||
1818 | } | 1793 | } |
1819 | port_fp(fp) = pd; | 1794 | port_fp(fp) = pd; |
1820 | subport_fp(fp) = pd->port_cnt++; | 1795 | subport_fp(fp) = pd->port_cnt++; |
1821 | pd->port_subpid[subport_fp(fp)] = current->pid; | 1796 | pd->port_subpid[subport_fp(fp)] = |
1797 | get_pid(task_pid(current)); | ||
1822 | tidcursor_fp(fp) = 0; | 1798 | tidcursor_fp(fp) = 0; |
1823 | pd->active_slaves |= 1 << subport_fp(fp); | 1799 | pd->active_slaves |= 1 << subport_fp(fp); |
1824 | ipath_cdbg(PROC, | 1800 | ipath_cdbg(PROC, |
1825 | "%s[%u] %u sharing %s[%u] unit:port %u:%u\n", | 1801 | "%s[%u] %u sharing %s[%u] unit:port %u:%u\n", |
1826 | current->comm, current->pid, | 1802 | current->comm, current->pid, |
1827 | subport_fp(fp), | 1803 | subport_fp(fp), |
1828 | pd->port_comm, pd->port_pid, | 1804 | pd->port_comm, pid_nr(pd->port_pid), |
1829 | dd->ipath_unit, pd->port_port); | 1805 | dd->ipath_unit, pd->port_port); |
1830 | ret = 1; | 1806 | ret = 1; |
1831 | goto done; | 1807 | goto done; |
@@ -1938,11 +1914,25 @@ static int ipath_do_user_init(struct file *fp, | |||
1938 | 1914 | ||
1939 | /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */ | 1915 | /* for now we do nothing with rcvhdrcnt: uinfo->spu_rcvhdrcnt */ |
1940 | 1916 | ||
1917 | /* some ports may get extra buffers, calculate that here */ | ||
1918 | if (pd->port_port <= dd->ipath_ports_extrabuf) | ||
1919 | pd->port_piocnt = dd->ipath_pbufsport + 1; | ||
1920 | else | ||
1921 | pd->port_piocnt = dd->ipath_pbufsport; | ||
1922 | |||
1941 | /* for right now, kernel piobufs are at end, so port 1 is at 0 */ | 1923 | /* for right now, kernel piobufs are at end, so port 1 is at 0 */ |
1924 | if (pd->port_port <= dd->ipath_ports_extrabuf) | ||
1925 | pd->port_pio_base = (dd->ipath_pbufsport + 1) | ||
1926 | * (pd->port_port - 1); | ||
1927 | else | ||
1928 | pd->port_pio_base = dd->ipath_ports_extrabuf + | ||
1929 | dd->ipath_pbufsport * (pd->port_port - 1); | ||
1942 | pd->port_piobufs = dd->ipath_piobufbase + | 1930 | pd->port_piobufs = dd->ipath_piobufbase + |
1943 | dd->ipath_pbufsport * (pd->port_port - 1) * dd->ipath_palign; | 1931 | pd->port_pio_base * dd->ipath_palign; |
1944 | ipath_cdbg(VERBOSE, "Set base of piobufs for port %u to 0x%x\n", | 1932 | ipath_cdbg(VERBOSE, "piobuf base for port %u is 0x%x, piocnt %u," |
1945 | pd->port_port, pd->port_piobufs); | 1933 | " first pio %u\n", pd->port_port, pd->port_piobufs, |
1934 | pd->port_piocnt, pd->port_pio_base); | ||
1935 | ipath_chg_pioavailkernel(dd, pd->port_pio_base, pd->port_piocnt, 0); | ||
1946 | 1936 | ||
1947 | /* | 1937 | /* |
1948 | * Now allocate the rcvhdr Q and eager TIDs; skip the TID | 1938 | * Now allocate the rcvhdr Q and eager TIDs; skip the TID |
@@ -2077,7 +2067,8 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
2077 | * the slave(s) don't wait for receive data forever. | 2067 | * the slave(s) don't wait for receive data forever. |
2078 | */ | 2068 | */ |
2079 | pd->active_slaves &= ~(1 << fd->subport); | 2069 | pd->active_slaves &= ~(1 << fd->subport); |
2080 | pd->port_subpid[fd->subport] = 0; | 2070 | put_pid(pd->port_subpid[fd->subport]); |
2071 | pd->port_subpid[fd->subport] = NULL; | ||
2081 | mutex_unlock(&ipath_mutex); | 2072 | mutex_unlock(&ipath_mutex); |
2082 | goto bail; | 2073 | goto bail; |
2083 | } | 2074 | } |
@@ -2085,7 +2076,7 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
2085 | 2076 | ||
2086 | if (pd->port_hdrqfull) { | 2077 | if (pd->port_hdrqfull) { |
2087 | ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors " | 2078 | ipath_cdbg(PROC, "%s[%u] had %u rcvhdrqfull errors " |
2088 | "during run\n", pd->port_comm, pd->port_pid, | 2079 | "during run\n", pd->port_comm, pid_nr(pd->port_pid), |
2089 | pd->port_hdrqfull); | 2080 | pd->port_hdrqfull); |
2090 | pd->port_hdrqfull = 0; | 2081 | pd->port_hdrqfull = 0; |
2091 | } | 2082 | } |
@@ -2107,7 +2098,6 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
2107 | } | 2098 | } |
2108 | 2099 | ||
2109 | if (dd->ipath_kregbase) { | 2100 | if (dd->ipath_kregbase) { |
2110 | int i; | ||
2111 | /* atomically clear receive enable port and intr avail. */ | 2101 | /* atomically clear receive enable port and intr avail. */ |
2112 | clear_bit(dd->ipath_r_portenable_shift + port, | 2102 | clear_bit(dd->ipath_r_portenable_shift + port, |
2113 | &dd->ipath_rcvctrl); | 2103 | &dd->ipath_rcvctrl); |
@@ -2136,9 +2126,9 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
2136 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, | 2126 | ipath_write_kreg_port(dd, dd->ipath_kregs->kr_rcvhdraddr, |
2137 | pd->port_port, dd->ipath_dummy_hdrq_phys); | 2127 | pd->port_port, dd->ipath_dummy_hdrq_phys); |
2138 | 2128 | ||
2139 | i = dd->ipath_pbufsport * (port - 1); | 2129 | ipath_disarm_piobufs(dd, pd->port_pio_base, pd->port_piocnt); |
2140 | ipath_disarm_piobufs(dd, i, dd->ipath_pbufsport); | 2130 | ipath_chg_pioavailkernel(dd, pd->port_pio_base, |
2141 | ipath_chg_pioavailkernel(dd, i, dd->ipath_pbufsport, 1); | 2131 | pd->port_piocnt, 1); |
2142 | 2132 | ||
2143 | dd->ipath_f_clear_tids(dd, pd->port_port); | 2133 | dd->ipath_f_clear_tids(dd, pd->port_port); |
2144 | 2134 | ||
@@ -2146,11 +2136,12 @@ static int ipath_close(struct inode *in, struct file *fp) | |||
2146 | unlock_expected_tids(pd); | 2136 | unlock_expected_tids(pd); |
2147 | ipath_stats.sps_ports--; | 2137 | ipath_stats.sps_ports--; |
2148 | ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n", | 2138 | ipath_cdbg(PROC, "%s[%u] closed port %u:%u\n", |
2149 | pd->port_comm, pd->port_pid, | 2139 | pd->port_comm, pid_nr(pd->port_pid), |
2150 | dd->ipath_unit, port); | 2140 | dd->ipath_unit, port); |
2151 | } | 2141 | } |
2152 | 2142 | ||
2153 | pd->port_pid = 0; | 2143 | put_pid(pd->port_pid); |
2144 | pd->port_pid = NULL; | ||
2154 | dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */ | 2145 | dd->ipath_pd[pd->port_port] = NULL; /* before releasing mutex */ |
2155 | mutex_unlock(&ipath_mutex); | 2146 | mutex_unlock(&ipath_mutex); |
2156 | ipath_free_pddata(dd, pd); /* after releasing the mutex */ | 2147 | ipath_free_pddata(dd, pd); /* after releasing the mutex */ |