On Mon, Jul 18, 2016 at 08:14:47PM +0200, mhornung.linux@xxxxxxxxx wrote: > Hello, > > I have some questions about the locking techniques used inside > file drivers/staging/most/hdm-usb/hdm_usb.c. Eeek, never use anything from drivers/staging/ as a good example of anything. Please, that code is in staging for a good reason, only worry about code outside of drivers/staging/ for good examples. > > The one and only call to function free_anchored_buffers is locked by a Mutex: > > ---------------------------------------------------------------------------- > ... > mutex_lock(&mdev->io_mutex); > free_anchored_buffers(mdev, channel); > if (mdev->padding_active[channel]) > mdev->padding_active[channel] = false; > > if (mdev->conf[channel].data_type == MOST_CH_ASYNC) { > del_timer_sync(&mdev->link_stat_timer); > cancel_work_sync(&mdev->poll_work_obj); > } > mutex_unlock(&mdev->io_mutex); > ... > ---------------------------------------------------------------------------- > > Then, inside function free_anchored_buffers, they use a (from my point of view) > somewhat complex spinlock variant: > > ---------------------------------------------------------------------------- > static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel) > { > struct mbo *mbo; > struct buf_anchor *anchor, *tmp; > unsigned long flags; > > spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags); > list_for_each_entry_safe(anchor, tmp, &mdev->anchor_list[channel], > list) { > struct urb *urb = anchor->urb; > > spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags); > if (likely(urb)) { > mbo = urb->context; > if (!irqs_disabled()) { > usb_kill_urb(urb); > } else { > usb_unlink_urb(urb); > wait_for_completion(&anchor->urb_compl); > } > if ((mbo) && (mbo->complete)) { > mbo->status = MBO_E_CLOSE; > mbo->processed_length = 0; > mbo->complete(mbo); > } > usb_free_urb(urb); > } > spin_lock_irqsave(&mdev->anchor_list_lock[channel], flags); > list_del(&anchor->list); > cancel_work_sync(&anchor->clear_work_obj); > kfree(anchor); > } > spin_unlock_irqrestore(&mdev->anchor_list_lock[channel], flags); > } > ---------------------------------------------------------------------------- > > To my questions: > > #1: What is the intention of locking a whole function with a Mutex and then > using spinlocks inside the function? Wouldn't it be sufficient to use > one locking technique? > #2: Why is the spinlock not just locking the whole list_for_each_entry part or > just the list_del(&anchor->list)? Why not ask the authors and maintainers of these files? They would be the best to answer them, don't you think? thanks, greg k-h _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies