Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (8208): uvcvideo: Use GFP_NOIO when allocating memory during resume

The swap device might still be asleep, so memory allocated in the resume
handler must use GFP_NOIO. Thanks to Oliver Neukum for catching and reporting
this bug.

Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Laurent Pinchart and committed by
Mauro Carvalho Chehab
29135878 233548a2

+13 -13
+1 -1
drivers/media/video/uvc/uvc_status.c
··· 203 203 if (dev->int_urb == NULL) 204 204 return 0; 205 205 206 - return usb_submit_urb(dev->int_urb, GFP_KERNEL); 206 + return usb_submit_urb(dev->int_urb, GFP_NOIO); 207 207 }
+12 -12
drivers/media/video/uvc/uvc_video.c
··· 586 586 * is given by the endpoint. 587 587 */ 588 588 static int uvc_init_video_isoc(struct uvc_video_device *video, 589 - struct usb_host_endpoint *ep) 589 + struct usb_host_endpoint *ep, gfp_t gfp_flags) 590 590 { 591 591 struct urb *urb; 592 592 unsigned int npackets, i, j; ··· 611 611 size = npackets * psize; 612 612 613 613 for (i = 0; i < UVC_URBS; ++i) { 614 - urb = usb_alloc_urb(npackets, GFP_KERNEL); 614 + urb = usb_alloc_urb(npackets, gfp_flags); 615 615 if (urb == NULL) { 616 616 uvc_uninit_video(video); 617 617 return -ENOMEM; 618 618 } 619 619 620 620 video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, 621 - size, GFP_KERNEL, &urb->transfer_dma); 621 + size, gfp_flags, &urb->transfer_dma); 622 622 if (video->urb_buffer[i] == NULL) { 623 623 usb_free_urb(urb); 624 624 uvc_uninit_video(video); ··· 652 652 * given by the endpoint. 653 653 */ 654 654 static int uvc_init_video_bulk(struct uvc_video_device *video, 655 - struct usb_host_endpoint *ep) 655 + struct usb_host_endpoint *ep, gfp_t gfp_flags) 656 656 { 657 657 struct urb *urb; 658 658 unsigned int pipe, i; ··· 674 674 pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); 675 675 676 676 for (i = 0; i < UVC_URBS; ++i) { 677 - urb = usb_alloc_urb(0, GFP_KERNEL); 677 + urb = usb_alloc_urb(0, gfp_flags); 678 678 if (urb == NULL) { 679 679 uvc_uninit_video(video); 680 680 return -ENOMEM; 681 681 } 682 682 683 683 video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, 684 - size, GFP_KERNEL, &urb->transfer_dma); 684 + size, gfp_flags, &urb->transfer_dma); 685 685 if (video->urb_buffer[i] == NULL) { 686 686 usb_free_urb(urb); 687 687 uvc_uninit_video(video); ··· 702 702 /* 703 703 * Initialize isochronous/bulk URBs and allocate transfer buffers. 704 704 */ 705 - static int uvc_init_video(struct uvc_video_device *video) 705 + static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) 706 706 { 707 707 struct usb_interface *intf = video->streaming->intf; 708 708 struct usb_host_interface *alts; ··· 747 747 if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) 748 748 return ret; 749 749 750 - ret = uvc_init_video_isoc(video, ep); 750 + ret = uvc_init_video_isoc(video, ep, gfp_flags); 751 751 } else { 752 752 /* Bulk endpoint, proceed to URB initialization. */ 753 753 ep = uvc_find_endpoint(&intf->altsetting[0], ··· 755 755 if (ep == NULL) 756 756 return -EIO; 757 757 758 - ret = uvc_init_video_bulk(video, ep); 758 + ret = uvc_init_video_bulk(video, ep, gfp_flags); 759 759 } 760 760 761 761 if (ret < 0) ··· 763 763 764 764 /* Submit the URBs. */ 765 765 for (i = 0; i < UVC_URBS; ++i) { 766 - if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) { 766 + if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) { 767 767 uvc_printk(KERN_ERR, "Failed to submit URB %u " 768 768 "(%d).\n", i, ret); 769 769 uvc_uninit_video(video); ··· 818 818 if (!uvc_queue_streaming(&video->queue)) 819 819 return 0; 820 820 821 - if ((ret = uvc_init_video(video)) < 0) 821 + if ((ret = uvc_init_video(video, GFP_NOIO)) < 0) 822 822 uvc_queue_enable(&video->queue, 0); 823 823 824 824 return ret; ··· 930 930 if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) 931 931 return ret; 932 932 933 - return uvc_init_video(video); 933 + return uvc_init_video(video, GFP_KERNEL); 934 934 }