* [bug report] IB/usnic: Add Cisco VIC low-level hardware driver
@ 2021-07-05 10:23 Dan Carpenter
2021-07-05 13:47 ` Robin Murphy
0 siblings, 1 reply; 5+ messages in thread
From: Dan Carpenter @ 2021-07-05 10:23 UTC (permalink / raw)
To: umalhi; +Cc: linux-rdma, iommu
[ Ancient code, but the bug seems real enough still. -dan ]
Hello Upinder Malhi,
The patch e3cf00d0a87f: "IB/usnic: Add Cisco VIC low-level hardware
driver" from Sep 10, 2013, leads to the following static checker
warning:
drivers/iommu/iommu.c:2482 iommu_map()
warn: sleeping in atomic context
drivers/infiniband/hw/usnic/usnic_uiom.c
244 static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
245 struct usnic_uiom_reg *uiomr)
This function is always called from usnic_uiom_reg_get() which is holding
spin_lock(&pd->lock); so it can't sleep.
246 {
247 int i, err;
248 size_t size;
249 struct usnic_uiom_chunk *chunk;
250 struct usnic_uiom_interval_node *interval_node;
251 dma_addr_t pa;
252 dma_addr_t pa_start = 0;
253 dma_addr_t pa_end = 0;
254 long int va_start = -EINVAL;
255 struct usnic_uiom_pd *pd = uiomr->pd;
256 long int va = uiomr->va & PAGE_MASK;
257 int flags = IOMMU_READ | IOMMU_CACHE;
258
259 flags |= (uiomr->writable) ? IOMMU_WRITE : 0;
260 chunk = list_first_entry(&uiomr->chunk_list, struct usnic_uiom_chunk,
261 list);
262 list_for_each_entry(interval_node, intervals, link) {
263 iter_chunk:
264 for (i = 0; i < chunk->nents; i++, va += PAGE_SIZE) {
265 pa = sg_phys(&chunk->page_list[i]);
266 if ((va >> PAGE_SHIFT) < interval_node->start)
267 continue;
268
269 if ((va >> PAGE_SHIFT) == interval_node->start) {
270 /* First page of the interval */
271 va_start = va;
272 pa_start = pa;
273 pa_end = pa;
274 }
275
276 WARN_ON(va_start == -EINVAL);
277
278 if ((pa_end + PAGE_SIZE != pa) &&
279 (pa != pa_start)) {
280 /* PAs are not contiguous */
281 size = pa_end - pa_start + PAGE_SIZE;
282 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x",
283 va_start, &pa_start, size, flags);
284 err = iommu_map(pd->domain, va_start, pa_start,
285 size, flags);
The iommu_map() function sleeps.
286 if (err) {
287 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
288 va_start, &pa_start, size, err);
289 goto err_out;
290 }
291 va_start = va;
292 pa_start = pa;
293 pa_end = pa;
294 }
295
296 if ((va >> PAGE_SHIFT) == interval_node->last) {
297 /* Last page of the interval */
298 size = pa - pa_start + PAGE_SIZE;
299 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n",
300 va_start, &pa_start, size, flags);
301 err = iommu_map(pd->domain, va_start, pa_start,
302 size, flags);
iommu_map() again.
303 if (err) {
304 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
305 va_start, &pa_start, size, err);
306 goto err_out;
307 }
308 break;
309 }
310
311 if (pa != pa_start)
312 pa_end += PAGE_SIZE;
313 }
314
315 if (i == chunk->nents) {
316 /*
317 * Hit last entry of the chunk,
318 * hence advance to next chunk
319 */
320 chunk = list_first_entry(&chunk->list,
321 struct usnic_uiom_chunk,
322 list);
323 goto iter_chunk;
324 }
325 }
326
327 return 0;
328
329 err_out:
330 usnic_uiom_unmap_sorted_intervals(intervals, pd);
331 return err;
332 }
regards,
dan carpenter
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [bug report] IB/usnic: Add Cisco VIC low-level hardware driver
2021-07-05 10:23 [bug report] IB/usnic: Add Cisco VIC low-level hardware driver Dan Carpenter
@ 2021-07-05 13:47 ` Robin Murphy
2021-07-05 15:21 ` Jason Gunthorpe
0 siblings, 1 reply; 5+ messages in thread
From: Robin Murphy @ 2021-07-05 13:47 UTC (permalink / raw)
To: Dan Carpenter, umalhi; +Cc: linux-rdma, iommu
On 2021-07-05 11:23, Dan Carpenter wrote:
> [ Ancient code, but the bug seems real enough still. -dan ]
>
> Hello Upinder Malhi,
>
> The patch e3cf00d0a87f: "IB/usnic: Add Cisco VIC low-level hardware
> driver" from Sep 10, 2013, leads to the following static checker
> warning:
>
> drivers/iommu/iommu.c:2482 iommu_map()
> warn: sleeping in atomic context
>
> drivers/infiniband/hw/usnic/usnic_uiom.c
> 244 static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
> 245 struct usnic_uiom_reg *uiomr)
>
> This function is always called from usnic_uiom_reg_get() which is holding
> spin_lock(&pd->lock); so it can't sleep.
FWIW back in those days it wasn't really well defined whether
iommu_map() was callable from non-sleeping contexts (the arch/arm DMA
API code relied on it, for instance). It was only formalised 2 years ago
by 781ca2de89ba ("iommu: Add gfp parameter to iommu_ops::map") which
introduced the might_sleep() check that's firing there. I guess these
calls want to be updated to iommu_map_atomic() now.
Robin.
> 246 {
> 247 int i, err;
> 248 size_t size;
> 249 struct usnic_uiom_chunk *chunk;
> 250 struct usnic_uiom_interval_node *interval_node;
> 251 dma_addr_t pa;
> 252 dma_addr_t pa_start = 0;
> 253 dma_addr_t pa_end = 0;
> 254 long int va_start = -EINVAL;
> 255 struct usnic_uiom_pd *pd = uiomr->pd;
> 256 long int va = uiomr->va & PAGE_MASK;
> 257 int flags = IOMMU_READ | IOMMU_CACHE;
> 258
> 259 flags |= (uiomr->writable) ? IOMMU_WRITE : 0;
> 260 chunk = list_first_entry(&uiomr->chunk_list, struct usnic_uiom_chunk,
> 261 list);
> 262 list_for_each_entry(interval_node, intervals, link) {
> 263 iter_chunk:
> 264 for (i = 0; i < chunk->nents; i++, va += PAGE_SIZE) {
> 265 pa = sg_phys(&chunk->page_list[i]);
> 266 if ((va >> PAGE_SHIFT) < interval_node->start)
> 267 continue;
> 268
> 269 if ((va >> PAGE_SHIFT) == interval_node->start) {
> 270 /* First page of the interval */
> 271 va_start = va;
> 272 pa_start = pa;
> 273 pa_end = pa;
> 274 }
> 275
> 276 WARN_ON(va_start == -EINVAL);
> 277
> 278 if ((pa_end + PAGE_SIZE != pa) &&
> 279 (pa != pa_start)) {
> 280 /* PAs are not contiguous */
> 281 size = pa_end - pa_start + PAGE_SIZE;
> 282 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x",
> 283 va_start, &pa_start, size, flags);
> 284 err = iommu_map(pd->domain, va_start, pa_start,
> 285 size, flags);
>
> The iommu_map() function sleeps.
>
> 286 if (err) {
> 287 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
> 288 va_start, &pa_start, size, err);
> 289 goto err_out;
> 290 }
> 291 va_start = va;
> 292 pa_start = pa;
> 293 pa_end = pa;
> 294 }
> 295
> 296 if ((va >> PAGE_SHIFT) == interval_node->last) {
> 297 /* Last page of the interval */
> 298 size = pa - pa_start + PAGE_SIZE;
> 299 usnic_dbg("va 0x%lx pa %pa size 0x%zx flags 0x%x\n",
> 300 va_start, &pa_start, size, flags);
> 301 err = iommu_map(pd->domain, va_start, pa_start,
> 302 size, flags);
>
> iommu_map() again.
>
> 303 if (err) {
> 304 usnic_err("Failed to map va 0x%lx pa %pa size 0x%zx with err %d\n",
> 305 va_start, &pa_start, size, err);
> 306 goto err_out;
> 307 }
> 308 break;
> 309 }
> 310
> 311 if (pa != pa_start)
> 312 pa_end += PAGE_SIZE;
> 313 }
> 314
> 315 if (i == chunk->nents) {
> 316 /*
> 317 * Hit last entry of the chunk,
> 318 * hence advance to next chunk
> 319 */
> 320 chunk = list_first_entry(&chunk->list,
> 321 struct usnic_uiom_chunk,
> 322 list);
> 323 goto iter_chunk;
> 324 }
> 325 }
> 326
> 327 return 0;
> 328
> 329 err_out:
> 330 usnic_uiom_unmap_sorted_intervals(intervals, pd);
> 331 return err;
> 332 }
>
> regards,
> dan carpenter
> _______________________________________________
> iommu mailing list
> iommu@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
>
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [bug report] IB/usnic: Add Cisco VIC low-level hardware driver
2021-07-05 13:47 ` Robin Murphy
@ 2021-07-05 15:21 ` Jason Gunthorpe
2021-07-05 15:39 ` Robin Murphy
2021-07-05 15:45 ` Dan Carpenter
0 siblings, 2 replies; 5+ messages in thread
From: Jason Gunthorpe @ 2021-07-05 15:21 UTC (permalink / raw)
To: Robin Murphy, Christian Benvenuti, Nelson Escobar
Cc: linux-rdma, iommu, umalhi, Dan Carpenter
On Mon, Jul 05, 2021 at 02:47:36PM +0100, Robin Murphy wrote:
> On 2021-07-05 11:23, Dan Carpenter wrote:
> > [ Ancient code, but the bug seems real enough still. -dan ]
> >
> > Hello Upinder Malhi,
> >
> > The patch e3cf00d0a87f: "IB/usnic: Add Cisco VIC low-level hardware
> > driver" from Sep 10, 2013, leads to the following static checker
> > warning:
> >
> > drivers/iommu/iommu.c:2482 iommu_map()
> > warn: sleeping in atomic context
> >
> > drivers/infiniband/hw/usnic/usnic_uiom.c
> > 244 static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
> > 245 struct usnic_uiom_reg *uiomr)
> >
> > This function is always called from usnic_uiom_reg_get() which is holding
> > spin_lock(&pd->lock); so it can't sleep.
>
> FWIW back in those days it wasn't really well defined whether iommu_map()
> was callable from non-sleeping contexts (the arch/arm DMA API code relied on
> it, for instance). It was only formalised 2 years ago by 781ca2de89ba
> ("iommu: Add gfp parameter to iommu_ops::map") which introduced the
> might_sleep() check that's firing there. I guess these calls want to be
> updated to iommu_map_atomic() now.
Does this mean this driver doesn't work at all upstream? I would be
quite interested to delete it.
Jason
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [bug report] IB/usnic: Add Cisco VIC low-level hardware driver
2021-07-05 15:21 ` Jason Gunthorpe
@ 2021-07-05 15:39 ` Robin Murphy
2021-07-05 15:45 ` Dan Carpenter
1 sibling, 0 replies; 5+ messages in thread
From: Robin Murphy @ 2021-07-05 15:39 UTC (permalink / raw)
To: Jason Gunthorpe, Christian Benvenuti, Nelson Escobar
Cc: linux-rdma, iommu, umalhi, Dan Carpenter
On 2021-07-05 16:21, Jason Gunthorpe wrote:
> On Mon, Jul 05, 2021 at 02:47:36PM +0100, Robin Murphy wrote:
>> On 2021-07-05 11:23, Dan Carpenter wrote:
>>> [ Ancient code, but the bug seems real enough still. -dan ]
>>>
>>> Hello Upinder Malhi,
>>>
>>> The patch e3cf00d0a87f: "IB/usnic: Add Cisco VIC low-level hardware
>>> driver" from Sep 10, 2013, leads to the following static checker
>>> warning:
>>>
>>> drivers/iommu/iommu.c:2482 iommu_map()
>>> warn: sleeping in atomic context
>>>
>>> drivers/infiniband/hw/usnic/usnic_uiom.c
>>> 244 static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
>>> 245 struct usnic_uiom_reg *uiomr)
>>>
>>> This function is always called from usnic_uiom_reg_get() which is holding
>>> spin_lock(&pd->lock); so it can't sleep.
>>
>> FWIW back in those days it wasn't really well defined whether iommu_map()
>> was callable from non-sleeping contexts (the arch/arm DMA API code relied on
>> it, for instance). It was only formalised 2 years ago by 781ca2de89ba
>> ("iommu: Add gfp parameter to iommu_ops::map") which introduced the
>> might_sleep() check that's firing there. I guess these calls want to be
>> updated to iommu_map_atomic() now.
>
> Does this mean this driver doesn't work at all upstream? I would be
> quite interested to delete it.
I think the only time it's actually in trouble is on AMD hardware if one
of those iommu_map() calls has to allocate a new pagetable page and that
allocation has to go down whichever reclaim path actually sleeps.
Historically all the other IOMMU drivers it might have come into contact
with already used GFP_ATOMIC for their internal allocations anyway (AMD
was the only one using a mutex instead of a spinlock internally), and
some like intel-iommu still haven't relaxed that even now.
Robin.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [bug report] IB/usnic: Add Cisco VIC low-level hardware driver
2021-07-05 15:21 ` Jason Gunthorpe
2021-07-05 15:39 ` Robin Murphy
@ 2021-07-05 15:45 ` Dan Carpenter
1 sibling, 0 replies; 5+ messages in thread
From: Dan Carpenter @ 2021-07-05 15:45 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Nelson Escobar, umalhi, linux-rdma, iommu, Robin Murphy,
Christian Benvenuti
On Mon, Jul 05, 2021 at 12:21:38PM -0300, Jason Gunthorpe wrote:
> On Mon, Jul 05, 2021 at 02:47:36PM +0100, Robin Murphy wrote:
> > On 2021-07-05 11:23, Dan Carpenter wrote:
> > > [ Ancient code, but the bug seems real enough still. -dan ]
> > >
> > > Hello Upinder Malhi,
> > >
> > > The patch e3cf00d0a87f: "IB/usnic: Add Cisco VIC low-level hardware
> > > driver" from Sep 10, 2013, leads to the following static checker
> > > warning:
> > >
> > > drivers/iommu/iommu.c:2482 iommu_map()
> > > warn: sleeping in atomic context
> > >
> > > drivers/infiniband/hw/usnic/usnic_uiom.c
> > > 244 static int usnic_uiom_map_sorted_intervals(struct list_head *intervals,
> > > 245 struct usnic_uiom_reg *uiomr)
> > >
> > > This function is always called from usnic_uiom_reg_get() which is holding
> > > spin_lock(&pd->lock); so it can't sleep.
> >
> > FWIW back in those days it wasn't really well defined whether iommu_map()
> > was callable from non-sleeping contexts (the arch/arm DMA API code relied on
> > it, for instance). It was only formalised 2 years ago by 781ca2de89ba
> > ("iommu: Add gfp parameter to iommu_ops::map") which introduced the
> > might_sleep() check that's firing there. I guess these calls want to be
> > updated to iommu_map_atomic() now.
>
> Does this mean this driver doesn't work at all upstream? I would be
> quite interested to delete it.
It just means it hasn't been used with CONFIG_DEBUG_ATOMIC_SLEEP enabled
within the past two years.
regards,
dan carpenter
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-07-05 15:46 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-07-05 10:23 [bug report] IB/usnic: Add Cisco VIC low-level hardware driver Dan Carpenter
2021-07-05 13:47 ` Robin Murphy
2021-07-05 15:21 ` Jason Gunthorpe
2021-07-05 15:39 ` Robin Murphy
2021-07-05 15:45 ` Dan Carpenter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox