|
133 | 133 | * Each address family might have different locking rules, so we have
|
134 | 134 | * one slock key per address family:
|
135 | 135 | */
|
136 |
| -struct lock_class_key af_family_keys[AF_MAX]; |
| 136 | +static struct lock_class_key af_family_keys[AF_MAX]; |
| 137 | +static struct lock_class_key af_family_slock_keys[AF_MAX]; |
| 138 | + |
| 139 | +#ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 140 | +/* |
| 141 | + * Make lock validator output more readable. (we pre-construct these |
| 142 | + * strings build-time, so that runtime initialization of socket |
| 143 | + * locks is fast): |
| 144 | + */ |
| 145 | +static const char *af_family_key_strings[AF_MAX+1] = { |
| 146 | + "sk_lock-AF_UNSPEC", "sk_lock-AF_UNIX" , "sk_lock-AF_INET" , |
| 147 | + "sk_lock-AF_AX25" , "sk_lock-AF_IPX" , "sk_lock-AF_APPLETALK", |
| 148 | + "sk_lock-AF_NETROM", "sk_lock-AF_BRIDGE" , "sk_lock-AF_ATMPVC" , |
| 149 | + "sk_lock-AF_X25" , "sk_lock-AF_INET6" , "sk_lock-AF_ROSE" , |
| 150 | + "sk_lock-AF_DECnet", "sk_lock-AF_NETBEUI" , "sk_lock-AF_SECURITY" , |
| 151 | + "sk_lock-AF_KEY" , "sk_lock-AF_NETLINK" , "sk_lock-AF_PACKET" , |
| 152 | + "sk_lock-AF_ASH" , "sk_lock-AF_ECONET" , "sk_lock-AF_ATMSVC" , |
| 153 | + "sk_lock-21" , "sk_lock-AF_SNA" , "sk_lock-AF_IRDA" , |
| 154 | + "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE" , "sk_lock-AF_LLC" , |
| 155 | + "sk_lock-27" , "sk_lock-28" , "sk_lock-29" , |
| 156 | + "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-AF_MAX" |
| 157 | +}; |
| 158 | +static const char *af_family_slock_key_strings[AF_MAX+1] = { |
| 159 | + "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
| 160 | + "slock-AF_AX25" , "slock-AF_IPX" , "slock-AF_APPLETALK", |
| 161 | + "slock-AF_NETROM", "slock-AF_BRIDGE" , "slock-AF_ATMPVC" , |
| 162 | + "slock-AF_X25" , "slock-AF_INET6" , "slock-AF_ROSE" , |
| 163 | + "slock-AF_DECnet", "slock-AF_NETBEUI" , "slock-AF_SECURITY" , |
| 164 | + "slock-AF_KEY" , "slock-AF_NETLINK" , "slock-AF_PACKET" , |
| 165 | + "slock-AF_ASH" , "slock-AF_ECONET" , "slock-AF_ATMSVC" , |
| 166 | + "slock-21" , "slock-AF_SNA" , "slock-AF_IRDA" , |
| 167 | + "slock-AF_PPPOX" , "slock-AF_WANPIPE" , "slock-AF_LLC" , |
| 168 | + "slock-27" , "slock-28" , "slock-29" , |
| 169 | + "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_MAX" |
| 170 | +}; |
| 171 | +#endif |
137 | 172 |
|
138 | 173 | /*
|
139 | 174 | * sk_callback_lock locking rules are per-address-family,
|
@@ -249,9 +284,16 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
|
249 | 284 | skb->dev = NULL;
|
250 | 285 |
|
251 | 286 | bh_lock_sock(sk);
|
252 |
| - if (!sock_owned_by_user(sk)) |
| 287 | + if (!sock_owned_by_user(sk)) { |
| 288 | + /* |
| 289 | + * trylock + unlock semantics: |
| 290 | + */ |
| 291 | + mutex_acquire(&sk->sk_lock.dep_map, 0, 1, _RET_IP_); |
| 292 | + |
253 | 293 | rc = sk->sk_backlog_rcv(sk, skb);
|
254 |
| - else |
| 294 | + |
| 295 | + mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); |
| 296 | + } else |
255 | 297 | sk_add_backlog(sk, skb);
|
256 | 298 | bh_unlock_sock(sk);
|
257 | 299 | out:
|
@@ -761,6 +803,33 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
761 | 803 | return 0;
|
762 | 804 | }
|
763 | 805 |
|
| 806 | +/* |
| 807 | + * Initialize an sk_lock. |
| 808 | + * |
| 809 | + * (We also register the sk_lock with the lock validator.) |
| 810 | + */ |
| 811 | +static void inline sock_lock_init(struct sock *sk) |
| 812 | +{ |
| 813 | + spin_lock_init(&sk->sk_lock.slock); |
| 814 | + sk->sk_lock.owner = NULL; |
| 815 | + init_waitqueue_head(&sk->sk_lock.wq); |
| 816 | + /* |
| 817 | + * Make sure we are not reinitializing a held lock: |
| 818 | + */ |
| 819 | + debug_check_no_locks_freed((void *)&sk->sk_lock, sizeof(sk->sk_lock)); |
| 820 | + |
| 821 | + /* |
| 822 | + * Mark both the sk_lock and the sk_lock.slock as a |
| 823 | + * per-address-family lock class: |
| 824 | + */ |
| 825 | + lockdep_set_class_and_name(&sk->sk_lock.slock, |
| 826 | + af_family_slock_keys + sk->sk_family, |
| 827 | + af_family_slock_key_strings[sk->sk_family]); |
| 828 | + lockdep_init_map(&sk->sk_lock.dep_map, |
| 829 | + af_family_key_strings[sk->sk_family], |
| 830 | + af_family_keys + sk->sk_family); |
| 831 | +} |
| 832 | + |
764 | 833 | /**
|
765 | 834 | * sk_alloc - All socket objects are allocated here
|
766 | 835 | * @family: protocol family
|
@@ -1465,24 +1534,34 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
1465 | 1534 | void fastcall lock_sock(struct sock *sk)
|
1466 | 1535 | {
|
1467 | 1536 | might_sleep();
|
1468 |
| - spin_lock_bh(&(sk->sk_lock.slock)); |
| 1537 | + spin_lock_bh(&sk->sk_lock.slock); |
1469 | 1538 | if (sk->sk_lock.owner)
|
1470 | 1539 | __lock_sock(sk);
|
1471 | 1540 | sk->sk_lock.owner = (void *)1;
|
1472 |
| - spin_unlock_bh(&(sk->sk_lock.slock)); |
| 1541 | + spin_unlock(&sk->sk_lock.slock); |
| 1542 | + /* |
| 1543 | + * The sk_lock has mutex_lock() semantics here: |
| 1544 | + */ |
| 1545 | + mutex_acquire(&sk->sk_lock.dep_map, 0, 0, _RET_IP_); |
| 1546 | + local_bh_enable(); |
1473 | 1547 | }
|
1474 | 1548 |
|
1475 | 1549 | EXPORT_SYMBOL(lock_sock);
|
1476 | 1550 |
|
1477 | 1551 | void fastcall release_sock(struct sock *sk)
|
1478 | 1552 | {
|
1479 |
| - spin_lock_bh(&(sk->sk_lock.slock)); |
| 1553 | + /* |
| 1554 | + * The sk_lock has mutex_unlock() semantics: |
| 1555 | + */ |
| 1556 | + mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); |
| 1557 | + |
| 1558 | + spin_lock_bh(&sk->sk_lock.slock); |
1480 | 1559 | if (sk->sk_backlog.tail)
|
1481 | 1560 | __release_sock(sk);
|
1482 | 1561 | sk->sk_lock.owner = NULL;
|
1483 |
| - if (waitqueue_active(&(sk->sk_lock.wq))) |
1484 |
| - wake_up(&(sk->sk_lock.wq)); |
1485 |
| - spin_unlock_bh(&(sk->sk_lock.slock)); |
| 1562 | + if (waitqueue_active(&sk->sk_lock.wq)) |
| 1563 | + wake_up(&sk->sk_lock.wq); |
| 1564 | + spin_unlock_bh(&sk->sk_lock.slock); |
1486 | 1565 | }
|
1487 | 1566 | EXPORT_SYMBOL(release_sock);
|
1488 | 1567 |
|
|
0 commit comments