On Tue, Jun 23, 2020 at 7:03 AM Kent Gibson <warthog618@xxxxxxxxx> wrote: > > Merge separate usage of test_bit/set_bit into test_and_set_bit to remove > the possibility of a race between the test and set. > > Similarly test_bit and clear_bit. > > In the existing code it is possible for two threads to race past the > test_bit and then set or clear the watch bit, and neither return EBUSY. I stumbled over this myself, but... > - if (test_bit(hwgpio, gcdev->watched_lines)) > + if (test_and_set_bit(hwgpio, gcdev->watched_lines)) > return -EBUSY; > > gpio_desc_to_lineinfo(desc, &lineinfo); > @@ -897,7 +897,6 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) > if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) > return -EFAULT; > > - set_bit(hwgpio, gcdev->watched_lines); > return 0; ...I think it's not an equivalent despite races involved. If you set bit and return error code, you will have the wrong state. ... > - if (!test_bit(hwgpio, gcdev->watched_lines)) > + if (!test_and_clear_bit(hwgpio, gcdev->watched_lines)) > return -EBUSY; > > - clear_bit(hwgpio, gcdev->watched_lines); > return 0; OTOH, this is okay as long as we have no code in between. So, I really prefer something better to do such checks. (Alas, I can't come up with a proposal right now) -- With Best Regards, Andy Shevchenko