Commit a695f16729e00995fe72baf0e8bee4bf9c232ae0

Authored by Frank Munzert
Committed by Heiko Carstens
1 parent 92bf435f38

[S390] vmur: Use wait queue instead of mutex to serialize open

If user space opens a unit record device node then vmur is leaving the kernel
with lock open_mutex still held to prevent other processes from opening the
device simultaneously. This causes lockdep to complain about a lock held when
returning to user space.
Now the mutex is replaced by a wait queue to serialize device open.

Signed-off-by: Frank Munzert <munzert@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>

Showing 2 changed files with 20 additions and 8 deletions Side-by-side Diff

drivers/s390/char/vmur.c
... ... @@ -100,7 +100,8 @@
100 100 urd->reclen = cdev->id.driver_info;
101 101 ccw_device_get_id(cdev, &urd->dev_id);
102 102 mutex_init(&urd->io_mutex);
103   - mutex_init(&urd->open_mutex);
  103 + init_waitqueue_head(&urd->wait);
  104 + spin_lock_init(&urd->open_lock);
104 105 atomic_set(&urd->ref_count, 1);
105 106 urd->cdev = cdev;
106 107 get_device(&cdev->dev);
107 108  
108 109  
109 110  
... ... @@ -678,17 +679,21 @@
678 679 if (!urd)
679 680 return -ENXIO;
680 681  
681   - if (file->f_flags & O_NONBLOCK) {
682   - if (!mutex_trylock(&urd->open_mutex)) {
  682 + spin_lock(&urd->open_lock);
  683 + while (urd->open_flag) {
  684 + spin_unlock(&urd->open_lock);
  685 + if (file->f_flags & O_NONBLOCK) {
683 686 rc = -EBUSY;
684 687 goto fail_put;
685 688 }
686   - } else {
687   - if (mutex_lock_interruptible(&urd->open_mutex)) {
  689 + if (wait_event_interruptible(urd->wait, urd->open_flag == 0)) {
688 690 rc = -ERESTARTSYS;
689 691 goto fail_put;
690 692 }
  693 + spin_lock(&urd->open_lock);
691 694 }
  695 + urd->open_flag++;
  696 + spin_unlock(&urd->open_lock);
692 697  
693 698 TRACE("ur_open\n");
694 699  
... ... @@ -720,7 +725,9 @@
720 725 fail_urfile_free:
721 726 urfile_free(urf);
722 727 fail_unlock:
723   - mutex_unlock(&urd->open_mutex);
  728 + spin_lock(&urd->open_lock);
  729 + urd->open_flag--;
  730 + spin_unlock(&urd->open_lock);
724 731 fail_put:
725 732 urdev_put(urd);
726 733 return rc;
... ... @@ -731,7 +738,10 @@
731 738 struct urfile *urf = file->private_data;
732 739  
733 740 TRACE("ur_release\n");
734   - mutex_unlock(&urf->urd->open_mutex);
  741 + spin_lock(&urf->urd->open_lock);
  742 + urf->urd->open_flag--;
  743 + spin_unlock(&urf->urd->open_lock);
  744 + wake_up_interruptible(&urf->urd->wait);
735 745 urdev_put(urf->urd);
736 746 urfile_free(urf);
737 747 return 0;
drivers/s390/char/vmur.h
... ... @@ -62,7 +62,6 @@
62 62 struct urdev {
63 63 struct ccw_device *cdev; /* Backpointer to ccw device */
64 64 struct mutex io_mutex; /* Serialises device IO */
65   - struct mutex open_mutex; /* Serialises access to device */
66 65 struct completion *io_done; /* do_ur_io waits; irq completes */
67 66 struct device *device;
68 67 struct cdev *char_device;
... ... @@ -71,6 +70,9 @@
71 70 int class; /* VM device class */
72 71 int io_request_rc; /* return code from I/O request */
73 72 atomic_t ref_count; /* reference counter */
  73 + wait_queue_head_t wait; /* wait queue to serialize open */
  74 + int open_flag; /* "urdev is open" flag */
  75 + spinlock_t open_lock; /* serialize critical sections */
74 76 };
75 77  
76 78 /*