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

Configure Feed

Select the types of activity you want to include in your feed.

Input: serio - use guard notation when acquiring mutexes and spinlocks

Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Link: https://lore.kernel.org/r/20240905041732.2034348-20-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

+66 -99
+66 -99
drivers/input/serio/serio.c
··· 38 38 39 39 static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) 40 40 { 41 - int retval; 41 + guard(mutex)(&serio->drv_mutex); 42 42 43 - mutex_lock(&serio->drv_mutex); 44 - retval = drv->connect(serio, drv); 45 - mutex_unlock(&serio->drv_mutex); 46 - 47 - return retval; 43 + return drv->connect(serio, drv); 48 44 } 49 45 50 46 static int serio_reconnect_driver(struct serio *serio) 51 47 { 52 - int retval = -1; 48 + guard(mutex)(&serio->drv_mutex); 53 49 54 - mutex_lock(&serio->drv_mutex); 55 50 if (serio->drv && serio->drv->reconnect) 56 - retval = serio->drv->reconnect(serio); 57 - mutex_unlock(&serio->drv_mutex); 51 + return serio->drv->reconnect(serio); 58 52 59 - return retval; 53 + return -1; 60 54 } 61 55 62 56 static void serio_disconnect_driver(struct serio *serio) 63 57 { 64 - mutex_lock(&serio->drv_mutex); 58 + guard(mutex)(&serio->drv_mutex); 59 + 65 60 if (serio->drv) 66 61 serio->drv->disconnect(serio); 67 - mutex_unlock(&serio->drv_mutex); 68 62 } 69 63 70 64 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) ··· 141 147 static struct serio_event *serio_get_event(void) 142 148 { 143 149 struct serio_event *event = NULL; 144 - unsigned long flags; 145 150 146 - spin_lock_irqsave(&serio_event_lock, flags); 151 + guard(spinlock_irqsave)(&serio_event_lock); 147 152 148 153 if (!list_empty(&serio_event_list)) { 149 154 event = list_first_entry(&serio_event_list, ··· 150 157 list_del_init(&event->node); 151 158 } 152 159 153 - spin_unlock_irqrestore(&serio_event_lock, flags); 154 160 return event; 155 161 } 156 162 ··· 163 171 enum serio_event_type type) 164 172 { 165 173 struct serio_event *e, *next; 166 - unsigned long flags; 167 174 168 - spin_lock_irqsave(&serio_event_lock, flags); 175 + guard(spinlock_irqsave)(&serio_event_lock); 169 176 170 177 list_for_each_entry_safe(e, next, &serio_event_list, node) { 171 178 if (object == e->object) { ··· 180 189 serio_free_event(e); 181 190 } 182 191 } 183 - 184 - spin_unlock_irqrestore(&serio_event_lock, flags); 185 192 } 186 193 187 194 static void serio_handle_event(struct work_struct *work) 188 195 { 189 196 struct serio_event *event; 190 197 191 - mutex_lock(&serio_mutex); 198 + guard(mutex)(&serio_mutex); 192 199 193 200 while ((event = serio_get_event())) { 194 201 ··· 217 228 serio_remove_duplicate_events(event->object, event->type); 218 229 serio_free_event(event); 219 230 } 220 - 221 - mutex_unlock(&serio_mutex); 222 231 } 223 232 224 233 static DECLARE_WORK(serio_event_work, serio_handle_event); ··· 224 237 static int serio_queue_event(void *object, struct module *owner, 225 238 enum serio_event_type event_type) 226 239 { 227 - unsigned long flags; 228 240 struct serio_event *event; 229 - int retval = 0; 230 241 231 - spin_lock_irqsave(&serio_event_lock, flags); 242 + guard(spinlock_irqsave)(&serio_event_lock); 232 243 233 244 /* 234 245 * Scan event list for the other events for the same serio port, ··· 238 253 list_for_each_entry_reverse(event, &serio_event_list, node) { 239 254 if (event->object == object) { 240 255 if (event->type == event_type) 241 - goto out; 256 + return 0; 242 257 break; 243 258 } 244 259 } ··· 246 261 event = kmalloc(sizeof(*event), GFP_ATOMIC); 247 262 if (!event) { 248 263 pr_err("Not enough memory to queue event %d\n", event_type); 249 - retval = -ENOMEM; 250 - goto out; 264 + return -ENOMEM; 251 265 } 252 266 253 267 if (!try_module_get(owner)) { 254 268 pr_warn("Can't get module reference, dropping event %d\n", 255 269 event_type); 256 270 kfree(event); 257 - retval = -EINVAL; 258 - goto out; 271 + return -EINVAL; 259 272 } 260 273 261 274 event->type = event_type; ··· 263 280 list_add_tail(&event->node, &serio_event_list); 264 281 queue_work(system_long_wq, &serio_event_work); 265 282 266 - out: 267 - spin_unlock_irqrestore(&serio_event_lock, flags); 268 - return retval; 283 + return 0; 269 284 } 270 285 271 286 /* ··· 273 292 static void serio_remove_pending_events(void *object) 274 293 { 275 294 struct serio_event *event, *next; 276 - unsigned long flags; 277 295 278 - spin_lock_irqsave(&serio_event_lock, flags); 296 + guard(spinlock_irqsave)(&serio_event_lock); 279 297 280 298 list_for_each_entry_safe(event, next, &serio_event_list, node) { 281 299 if (event->object == object) { ··· 282 302 serio_free_event(event); 283 303 } 284 304 } 285 - 286 - spin_unlock_irqrestore(&serio_event_lock, flags); 287 305 } 288 306 289 307 /* ··· 293 315 static struct serio *serio_get_pending_child(struct serio *parent) 294 316 { 295 317 struct serio_event *event; 296 - struct serio *serio, *child = NULL; 297 - unsigned long flags; 318 + struct serio *serio; 298 319 299 - spin_lock_irqsave(&serio_event_lock, flags); 320 + guard(spinlock_irqsave)(&serio_event_lock); 300 321 301 322 list_for_each_entry(event, &serio_event_list, node) { 302 323 if (event->type == SERIO_REGISTER_PORT) { 303 324 serio = event->object; 304 - if (serio->parent == parent) { 305 - child = serio; 306 - break; 307 - } 325 + if (serio->parent == parent) 326 + return serio; 308 327 } 309 328 } 310 329 311 - spin_unlock_irqrestore(&serio_event_lock, flags); 312 - return child; 330 + return NULL; 313 331 } 314 332 315 333 /* ··· 356 382 struct device_driver *drv; 357 383 int error; 358 384 359 - error = mutex_lock_interruptible(&serio_mutex); 360 - if (error) 361 - return error; 362 - 363 - if (!strncmp(buf, "none", count)) { 364 - serio_disconnect_port(serio); 365 - } else if (!strncmp(buf, "reconnect", count)) { 366 - serio_reconnect_subtree(serio); 367 - } else if (!strncmp(buf, "rescan", count)) { 368 - serio_disconnect_port(serio); 369 - serio_find_driver(serio); 370 - serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); 371 - } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { 372 - serio_disconnect_port(serio); 373 - error = serio_bind_driver(serio, to_serio_driver(drv)); 374 - serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); 375 - } else { 376 - error = -EINVAL; 385 + scoped_cond_guard(mutex_intr, return -EINTR, &serio_mutex) { 386 + if (!strncmp(buf, "none", count)) { 387 + serio_disconnect_port(serio); 388 + } else if (!strncmp(buf, "reconnect", count)) { 389 + serio_reconnect_subtree(serio); 390 + } else if (!strncmp(buf, "rescan", count)) { 391 + serio_disconnect_port(serio); 392 + serio_find_driver(serio); 393 + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); 394 + } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { 395 + serio_disconnect_port(serio); 396 + error = serio_bind_driver(serio, to_serio_driver(drv)); 397 + serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); 398 + if (error) 399 + return error; 400 + } else { 401 + return -EINVAL; 402 + } 377 403 } 378 404 379 - mutex_unlock(&serio_mutex); 380 - 381 - return error ? error : count; 405 + return count; 382 406 } 383 407 384 408 static ssize_t serio_show_bind_mode(struct device *dev, struct device_attribute *attr, char *buf) ··· 498 526 int error; 499 527 500 528 if (parent) { 501 - serio_pause_rx(parent); 529 + guard(serio_pause_rx)(parent); 530 + 502 531 list_add_tail(&serio->child_node, &parent->children); 503 - serio_continue_rx(parent); 504 532 } 505 533 506 534 list_add_tail(&serio->node, &serio_list); ··· 532 560 serio->stop(serio); 533 561 534 562 if (serio->parent) { 535 - serio_pause_rx(serio->parent); 563 + guard(serio_pause_rx)(serio->parent); 564 + 536 565 list_del_init(&serio->child_node); 537 - serio_continue_rx(serio->parent); 538 566 serio->parent = NULL; 539 567 } 540 568 ··· 673 701 */ 674 702 void serio_unregister_port(struct serio *serio) 675 703 { 676 - mutex_lock(&serio_mutex); 704 + guard(mutex)(&serio_mutex); 705 + 677 706 serio_disconnect_port(serio); 678 707 serio_destroy_port(serio); 679 - mutex_unlock(&serio_mutex); 680 708 } 681 709 EXPORT_SYMBOL(serio_unregister_port); 682 710 ··· 687 715 { 688 716 struct serio *s, *next; 689 717 690 - mutex_lock(&serio_mutex); 718 + guard(mutex)(&serio_mutex); 719 + 691 720 list_for_each_entry_safe(s, next, &serio->children, child_node) { 692 721 serio_disconnect_port(s); 693 722 serio_destroy_port(s); 694 723 } 695 - mutex_unlock(&serio_mutex); 696 724 } 697 725 EXPORT_SYMBOL(serio_unregister_child_port); 698 726 ··· 756 784 757 785 static void serio_cleanup(struct serio *serio) 758 786 { 759 - mutex_lock(&serio->drv_mutex); 787 + guard(mutex)(&serio->drv_mutex); 788 + 760 789 if (serio->drv && serio->drv->cleanup) 761 790 serio->drv->cleanup(serio); 762 - mutex_unlock(&serio->drv_mutex); 763 791 } 764 792 765 793 static void serio_shutdown(struct device *dev) ··· 822 850 { 823 851 struct serio *serio; 824 852 825 - mutex_lock(&serio_mutex); 853 + guard(mutex)(&serio_mutex); 826 854 827 855 drv->manual_bind = true; /* so serio_find_driver ignores it */ 828 856 serio_remove_pending_events(drv); ··· 838 866 } 839 867 840 868 driver_unregister(&drv->driver); 841 - mutex_unlock(&serio_mutex); 842 869 } 843 870 EXPORT_SYMBOL(serio_unregister_driver); 844 871 845 872 static void serio_set_drv(struct serio *serio, struct serio_driver *drv) 846 873 { 847 - serio_pause_rx(serio); 874 + guard(serio_pause_rx)(serio); 875 + 848 876 serio->drv = drv; 849 - serio_continue_rx(serio); 850 877 } 851 878 852 879 static int serio_bus_match(struct device *dev, const struct device_driver *drv) ··· 906 935 struct serio *serio = to_serio_port(dev); 907 936 int error = -ENOENT; 908 937 909 - mutex_lock(&serio->drv_mutex); 910 - if (serio->drv && serio->drv->fast_reconnect) { 911 - error = serio->drv->fast_reconnect(serio); 912 - if (error && error != -ENOENT) 913 - dev_warn(dev, "fast reconnect failed with error %d\n", 914 - error); 938 + scoped_guard(mutex, &serio->drv_mutex) { 939 + if (serio->drv && serio->drv->fast_reconnect) { 940 + error = serio->drv->fast_reconnect(serio); 941 + if (error && error != -ENOENT) 942 + dev_warn(dev, "fast reconnect failed with error %d\n", 943 + error); 944 + } 915 945 } 916 - mutex_unlock(&serio->drv_mutex); 917 946 918 947 if (error) { 919 948 /* ··· 960 989 irqreturn_t serio_interrupt(struct serio *serio, 961 990 unsigned char data, unsigned int dfl) 962 991 { 963 - unsigned long flags; 964 - irqreturn_t ret = IRQ_NONE; 992 + guard(spinlock_irqsave)(&serio->lock); 965 993 966 - spin_lock_irqsave(&serio->lock, flags); 994 + if (likely(serio->drv)) 995 + return serio->drv->interrupt(serio, data, dfl); 967 996 968 - if (likely(serio->drv)) { 969 - ret = serio->drv->interrupt(serio, data, dfl); 970 - } else if (!dfl && device_is_registered(&serio->dev)) { 997 + if (!dfl && device_is_registered(&serio->dev)) { 971 998 serio_rescan(serio); 972 - ret = IRQ_HANDLED; 999 + return IRQ_HANDLED; 973 1000 } 974 1001 975 - spin_unlock_irqrestore(&serio->lock, flags); 976 - 977 - return ret; 1002 + return IRQ_NONE; 978 1003 } 979 1004 EXPORT_SYMBOL(serio_interrupt); 980 1005