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

[PATCH] IPMI: convert from semaphores to mutexes

Convert the remaining semaphores to mutexes in the IPMI driver. The
watchdog was using a semaphore as a real semaphore (for IPC), so the
conversion there required adding a completion.

Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Corey Minyard and committed by
Linus Torvalds
d6dfd131 8a3628d5

+63 -55
+9 -9
drivers/char/ipmi/ipmi_devintf.c
··· 42 42 #include <linux/slab.h> 43 43 #include <linux/devfs_fs_kernel.h> 44 44 #include <linux/ipmi.h> 45 - #include <asm/semaphore.h> 45 + #include <linux/mutex.h> 46 46 #include <linux/init.h> 47 47 #include <linux/device.h> 48 48 #include <linux/compat.h> ··· 55 55 struct file *file; 56 56 struct fasync_struct *fasync_queue; 57 57 wait_queue_head_t wait; 58 - struct semaphore recv_sem; 58 + struct mutex recv_mutex; 59 59 int default_retries; 60 60 unsigned int default_retry_time_ms; 61 61 }; ··· 141 141 INIT_LIST_HEAD(&(priv->recv_msgs)); 142 142 init_waitqueue_head(&priv->wait); 143 143 priv->fasync_queue = NULL; 144 - sema_init(&(priv->recv_sem), 1); 144 + mutex_init(&priv->recv_mutex); 145 145 146 146 /* Use the low-level defaults. */ 147 147 priv->default_retries = -1; ··· 285 285 break; 286 286 } 287 287 288 - /* We claim a semaphore because we don't want two 288 + /* We claim a mutex because we don't want two 289 289 users getting something from the queue at a time. 290 290 Since we have to release the spinlock before we can 291 291 copy the data to the user, it's possible another 292 292 user will grab something from the queue, too. Then 293 293 the messages might get out of order if something 294 294 fails and the message gets put back onto the 295 - queue. This semaphore prevents that problem. */ 296 - down(&(priv->recv_sem)); 295 + queue. This mutex prevents that problem. */ 296 + mutex_lock(&priv->recv_mutex); 297 297 298 298 /* Grab the message off the list. */ 299 299 spin_lock_irqsave(&(priv->recv_msg_lock), flags); ··· 352 352 goto recv_putback_on_err; 353 353 } 354 354 355 - up(&(priv->recv_sem)); 355 + mutex_unlock(&priv->recv_mutex); 356 356 ipmi_free_recv_msg(msg); 357 357 break; 358 358 ··· 362 362 spin_lock_irqsave(&(priv->recv_msg_lock), flags); 363 363 list_add(entry, &(priv->recv_msgs)); 364 364 spin_unlock_irqrestore(&(priv->recv_msg_lock), flags); 365 - up(&(priv->recv_sem)); 365 + mutex_unlock(&priv->recv_mutex); 366 366 break; 367 367 368 368 recv_err: 369 - up(&(priv->recv_sem)); 369 + mutex_unlock(&priv->recv_mutex); 370 370 break; 371 371 } 372 372
+12 -11
drivers/char/ipmi/ipmi_msghandler.c
··· 38 38 #include <linux/sched.h> 39 39 #include <linux/poll.h> 40 40 #include <linux/spinlock.h> 41 + #include <linux/mutex.h> 41 42 #include <linux/slab.h> 42 43 #include <linux/ipmi.h> 43 44 #include <linux/ipmi_smi.h> ··· 235 234 236 235 /* The list of command receivers that are registered for commands 237 236 on this interface. */ 238 - struct semaphore cmd_rcvrs_lock; 237 + struct mutex cmd_rcvrs_mutex; 239 238 struct list_head cmd_rcvrs; 240 239 241 240 /* Events that were queues because no one was there to receive ··· 388 387 389 388 /* Wholesale remove all the entries from the list in the 390 389 * interface and wait for RCU to know that none are in use. */ 391 - down(&intf->cmd_rcvrs_lock); 390 + mutex_lock(&intf->cmd_rcvrs_mutex); 392 391 list_add_rcu(&list, &intf->cmd_rcvrs); 393 392 list_del_rcu(&intf->cmd_rcvrs); 394 - up(&intf->cmd_rcvrs_lock); 393 + mutex_unlock(&intf->cmd_rcvrs_mutex); 395 394 synchronize_rcu(); 396 395 397 396 list_for_each_entry_safe(rcvr, rcvr2, &list, link) ··· 847 846 * since other things may be using it till we do 848 847 * synchronize_rcu()) then free everything in that list. 849 848 */ 850 - down(&intf->cmd_rcvrs_lock); 849 + mutex_lock(&intf->cmd_rcvrs_mutex); 851 850 list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) { 852 851 if (rcvr->user == user) { 853 852 list_del_rcu(&rcvr->link); ··· 855 854 rcvrs = rcvr; 856 855 } 857 856 } 858 - up(&intf->cmd_rcvrs_lock); 857 + mutex_unlock(&intf->cmd_rcvrs_mutex); 859 858 synchronize_rcu(); 860 859 while (rcvrs) { 861 860 rcvr = rcvrs; ··· 985 984 rcvr->netfn = netfn; 986 985 rcvr->user = user; 987 986 988 - down(&intf->cmd_rcvrs_lock); 987 + mutex_lock(&intf->cmd_rcvrs_mutex); 989 988 /* Make sure the command/netfn is not already registered. */ 990 989 entry = find_cmd_rcvr(intf, netfn, cmd); 991 990 if (entry) { ··· 996 995 list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); 997 996 998 997 out_unlock: 999 - up(&intf->cmd_rcvrs_lock); 998 + mutex_unlock(&intf->cmd_rcvrs_mutex); 1000 999 if (rv) 1001 1000 kfree(rcvr); 1002 1001 ··· 1010 1009 ipmi_smi_t intf = user->intf; 1011 1010 struct cmd_rcvr *rcvr; 1012 1011 1013 - down(&intf->cmd_rcvrs_lock); 1012 + mutex_lock(&intf->cmd_rcvrs_mutex); 1014 1013 /* Make sure the command/netfn is not already registered. */ 1015 1014 rcvr = find_cmd_rcvr(intf, netfn, cmd); 1016 1015 if ((rcvr) && (rcvr->user == user)) { 1017 1016 list_del_rcu(&rcvr->link); 1018 - up(&intf->cmd_rcvrs_lock); 1017 + mutex_unlock(&intf->cmd_rcvrs_mutex); 1019 1018 synchronize_rcu(); 1020 1019 kfree(rcvr); 1021 1020 return 0; 1022 1021 } else { 1023 - up(&intf->cmd_rcvrs_lock); 1022 + mutex_unlock(&intf->cmd_rcvrs_mutex); 1024 1023 return -ENOENT; 1025 1024 } 1026 1025 } ··· 2366 2365 spin_lock_init(&intf->events_lock); 2367 2366 INIT_LIST_HEAD(&intf->waiting_events); 2368 2367 intf->waiting_events_count = 0; 2369 - init_MUTEX(&intf->cmd_rcvrs_lock); 2368 + mutex_init(&intf->cmd_rcvrs_mutex); 2370 2369 INIT_LIST_HEAD(&intf->cmd_rcvrs); 2371 2370 init_waitqueue_head(&intf->waitq); 2372 2371
+12 -12
drivers/char/ipmi/ipmi_si_intf.c
··· 1014 1014 1015 1015 #define SI_MAX_PARMS 4 1016 1016 static LIST_HEAD(smi_infos); 1017 - static DECLARE_MUTEX(smi_infos_lock); 1017 + static DEFINE_MUTEX(smi_infos_lock); 1018 1018 static int smi_num; /* Used to sequence the SMIs */ 1019 1019 1020 1020 #define DEFAULT_REGSPACING 1 ··· 2276 2276 new_smi->slave_addr, new_smi->irq); 2277 2277 } 2278 2278 2279 - down(&smi_infos_lock); 2279 + mutex_lock(&smi_infos_lock); 2280 2280 if (!is_new_interface(new_smi)) { 2281 2281 printk(KERN_WARNING "ipmi_si: duplicate interface\n"); 2282 2282 rv = -EBUSY; ··· 2432 2432 2433 2433 list_add_tail(&new_smi->link, &smi_infos); 2434 2434 2435 - up(&smi_infos_lock); 2435 + mutex_unlock(&smi_infos_lock); 2436 2436 2437 2437 printk(" IPMI %s interface initialized\n",si_to_str[new_smi->si_type]); 2438 2438 ··· 2469 2469 2470 2470 kfree(new_smi); 2471 2471 2472 - up(&smi_infos_lock); 2472 + mutex_unlock(&smi_infos_lock); 2473 2473 2474 2474 return rv; 2475 2475 } ··· 2527 2527 #endif 2528 2528 2529 2529 if (si_trydefaults) { 2530 - down(&smi_infos_lock); 2530 + mutex_lock(&smi_infos_lock); 2531 2531 if (list_empty(&smi_infos)) { 2532 2532 /* No BMC was found, try defaults. */ 2533 - up(&smi_infos_lock); 2533 + mutex_unlock(&smi_infos_lock); 2534 2534 default_find_bmc(); 2535 2535 } else { 2536 - up(&smi_infos_lock); 2536 + mutex_unlock(&smi_infos_lock); 2537 2537 } 2538 2538 } 2539 2539 2540 - down(&smi_infos_lock); 2540 + mutex_lock(&smi_infos_lock); 2541 2541 if (list_empty(&smi_infos)) { 2542 - up(&smi_infos_lock); 2542 + mutex_unlock(&smi_infos_lock); 2543 2543 #ifdef CONFIG_PCI 2544 2544 pci_unregister_driver(&ipmi_pci_driver); 2545 2545 #endif 2546 2546 printk("ipmi_si: Unable to find any System Interface(s)\n"); 2547 2547 return -ENODEV; 2548 2548 } else { 2549 - up(&smi_infos_lock); 2549 + mutex_unlock(&smi_infos_lock); 2550 2550 return 0; 2551 2551 } 2552 2552 } ··· 2622 2622 pci_unregister_driver(&ipmi_pci_driver); 2623 2623 #endif 2624 2624 2625 - down(&smi_infos_lock); 2625 + mutex_lock(&smi_infos_lock); 2626 2626 list_for_each_entry_safe(e, tmp_e, &smi_infos, link) 2627 2627 cleanup_one_si(e); 2628 - up(&smi_infos_lock); 2628 + mutex_unlock(&smi_infos_lock); 2629 2629 2630 2630 driver_unregister(&ipmi_driver); 2631 2631 }
+30 -23
drivers/char/ipmi/ipmi_watchdog.c
··· 39 39 #include <linux/watchdog.h> 40 40 #include <linux/miscdevice.h> 41 41 #include <linux/init.h> 42 + #include <linux/completion.h> 42 43 #include <linux/rwsem.h> 43 44 #include <linux/errno.h> 44 45 #include <asm/uaccess.h> ··· 304 303 static void panic_halt_ipmi_heartbeat(void); 305 304 306 305 307 - /* We use a semaphore to make sure that only one thing can send a set 306 + /* We use a mutex to make sure that only one thing can send a set 308 307 timeout at one time, because we only have one copy of the data. 309 - The semaphore is claimed when the set_timeout is sent and freed 308 + The mutex is claimed when the set_timeout is sent and freed 310 309 when both messages are free. */ 311 310 static atomic_t set_timeout_tofree = ATOMIC_INIT(0); 312 - static DECLARE_MUTEX(set_timeout_lock); 311 + static DEFINE_MUTEX(set_timeout_lock); 312 + static DECLARE_COMPLETION(set_timeout_wait); 313 313 static void set_timeout_free_smi(struct ipmi_smi_msg *msg) 314 314 { 315 315 if (atomic_dec_and_test(&set_timeout_tofree)) 316 - up(&set_timeout_lock); 316 + complete(&set_timeout_wait); 317 317 } 318 318 static void set_timeout_free_recv(struct ipmi_recv_msg *msg) 319 319 { 320 320 if (atomic_dec_and_test(&set_timeout_tofree)) 321 - up(&set_timeout_lock); 321 + complete(&set_timeout_wait); 322 322 } 323 323 static struct ipmi_smi_msg set_timeout_smi_msg = 324 324 { ··· 401 399 402 400 403 401 /* We can only send one of these at a time. */ 404 - down(&set_timeout_lock); 402 + mutex_lock(&set_timeout_lock); 405 403 406 404 atomic_set(&set_timeout_tofree, 2); 407 405 ··· 409 407 &set_timeout_recv_msg, 410 408 &send_heartbeat_now); 411 409 if (rv) { 412 - up(&set_timeout_lock); 413 - } else { 414 - if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) 415 - || ((send_heartbeat_now) 416 - && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) 417 - { 418 - rv = ipmi_heartbeat(); 419 - } 410 + mutex_unlock(&set_timeout_lock); 411 + goto out; 420 412 } 421 413 414 + wait_for_completion(&set_timeout_wait); 415 + 416 + if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) 417 + || ((send_heartbeat_now) 418 + && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) 419 + { 420 + rv = ipmi_heartbeat(); 421 + } 422 + mutex_unlock(&set_timeout_lock); 423 + 424 + out: 422 425 return rv; 423 426 } 424 427 ··· 465 458 The semaphore is claimed when the set_timeout is sent and freed 466 459 when both messages are free. */ 467 460 static atomic_t heartbeat_tofree = ATOMIC_INIT(0); 468 - static DECLARE_MUTEX(heartbeat_lock); 469 - static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock); 461 + static DEFINE_MUTEX(heartbeat_lock); 462 + static DECLARE_COMPLETION(heartbeat_wait); 470 463 static void heartbeat_free_smi(struct ipmi_smi_msg *msg) 471 464 { 472 465 if (atomic_dec_and_test(&heartbeat_tofree)) 473 - up(&heartbeat_wait_lock); 466 + complete(&heartbeat_wait); 474 467 } 475 468 static void heartbeat_free_recv(struct ipmi_recv_msg *msg) 476 469 { 477 470 if (atomic_dec_and_test(&heartbeat_tofree)) 478 - up(&heartbeat_wait_lock); 471 + complete(&heartbeat_wait); 479 472 } 480 473 static struct ipmi_smi_msg heartbeat_smi_msg = 481 474 { ··· 518 511 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); 519 512 } 520 513 521 - down(&heartbeat_lock); 514 + mutex_lock(&heartbeat_lock); 522 515 523 516 atomic_set(&heartbeat_tofree, 2); 524 517 525 518 /* Don't reset the timer if we have the timer turned off, that 526 519 re-enables the watchdog. */ 527 520 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) { 528 - up(&heartbeat_lock); 521 + mutex_unlock(&heartbeat_lock); 529 522 return 0; 530 523 } 531 524 ··· 546 539 &heartbeat_recv_msg, 547 540 1); 548 541 if (rv) { 549 - up(&heartbeat_lock); 542 + mutex_unlock(&heartbeat_lock); 550 543 printk(KERN_WARNING PFX "heartbeat failure: %d\n", 551 544 rv); 552 545 return rv; 553 546 } 554 547 555 548 /* Wait for the heartbeat to be sent. */ 556 - down(&heartbeat_wait_lock); 549 + wait_for_completion(&heartbeat_wait); 557 550 558 551 if (heartbeat_recv_msg.msg.data[0] != 0) { 559 552 /* Got an error in the heartbeat response. It was already ··· 562 555 rv = -EINVAL; 563 556 } 564 557 565 - up(&heartbeat_lock); 558 + mutex_unlock(&heartbeat_lock); 566 559 567 560 return rv; 568 561 }