diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/skbuff.c | 7 | ||||
-rw-r--r-- | net/core/sock.c | 111 |
2 files changed, 110 insertions, 8 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7cfbdb215ba2..44f6a181a754 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -71,6 +71,13 @@ static kmem_cache_t *skbuff_head_cache __read_mostly; | |||
71 | static kmem_cache_t *skbuff_fclone_cache __read_mostly; | 71 | static kmem_cache_t *skbuff_fclone_cache __read_mostly; |
72 | 72 | ||
73 | /* | 73 | /* |
74 | * lockdep: lock class key used by skb_queue_head_init(): | ||
75 | */ | ||
76 | struct lock_class_key skb_queue_lock_key; | ||
77 | |||
78 | EXPORT_SYMBOL(skb_queue_lock_key); | ||
79 | |||
80 | /* | ||
74 | * Keep out-of-line to prevent kernel bloat. | 81 | * Keep out-of-line to prevent kernel bloat. |
75 | * __builtin_return_address is not used because it is not always | 82 | * __builtin_return_address is not used because it is not always |
76 | * reliable. | 83 | * reliable. |
diff --git a/net/core/sock.c b/net/core/sock.c index 533b9317144b..51fcfbc041a7 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -129,6 +129,53 @@ | |||
129 | #include <net/tcp.h> | 129 | #include <net/tcp.h> |
130 | #endif | 130 | #endif |
131 | 131 | ||
132 | /* | ||
133 | * Each address family might have different locking rules, so we have | ||
134 | * one slock key per address family: | ||
135 | */ | ||
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 | ||
172 | |||
173 | /* | ||
174 | * sk_callback_lock locking rules are per-address-family, | ||
175 | * so split the lock classes by using a per-AF key: | ||
176 | */ | ||
177 | static struct lock_class_key af_callback_keys[AF_MAX]; | ||
178 | |||
132 | /* Take into consideration the size of the struct sk_buff overhead in the | 179 | /* Take into consideration the size of the struct sk_buff overhead in the |
133 | * determination of these values, since that is non-constant across | 180 | * determination of these values, since that is non-constant across |
134 | * platforms. This makes socket queueing behavior and performance | 181 | * platforms. This makes socket queueing behavior and performance |
@@ -237,9 +284,16 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb) | |||
237 | skb->dev = NULL; | 284 | skb->dev = NULL; |
238 | 285 | ||
239 | bh_lock_sock(sk); | 286 | bh_lock_sock(sk); |
240 | 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 | |||
241 | rc = sk->sk_backlog_rcv(sk, skb); | 293 | rc = sk->sk_backlog_rcv(sk, skb); |
242 | else | 294 | |
295 | mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); | ||
296 | } else | ||
243 | sk_add_backlog(sk, skb); | 297 | sk_add_backlog(sk, skb); |
244 | bh_unlock_sock(sk); | 298 | bh_unlock_sock(sk); |
245 | out: | 299 | out: |
@@ -749,6 +803,33 @@ lenout: | |||
749 | return 0; | 803 | return 0; |
750 | } | 804 | } |
751 | 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 | |||
752 | /** | 833 | /** |
753 | * sk_alloc - All socket objects are allocated here | 834 | * sk_alloc - All socket objects are allocated here |
754 | * @family: protocol family | 835 | * @family: protocol family |
@@ -848,6 +929,8 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
848 | 929 | ||
849 | rwlock_init(&newsk->sk_dst_lock); | 930 | rwlock_init(&newsk->sk_dst_lock); |
850 | rwlock_init(&newsk->sk_callback_lock); | 931 | rwlock_init(&newsk->sk_callback_lock); |
932 | lockdep_set_class(&newsk->sk_callback_lock, | ||
933 | af_callback_keys + newsk->sk_family); | ||
851 | 934 | ||
852 | newsk->sk_dst_cache = NULL; | 935 | newsk->sk_dst_cache = NULL; |
853 | newsk->sk_wmem_queued = 0; | 936 | newsk->sk_wmem_queued = 0; |
@@ -1422,6 +1505,8 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1422 | 1505 | ||
1423 | rwlock_init(&sk->sk_dst_lock); | 1506 | rwlock_init(&sk->sk_dst_lock); |
1424 | rwlock_init(&sk->sk_callback_lock); | 1507 | rwlock_init(&sk->sk_callback_lock); |
1508 | lockdep_set_class(&sk->sk_callback_lock, | ||
1509 | af_callback_keys + sk->sk_family); | ||
1425 | 1510 | ||
1426 | sk->sk_state_change = sock_def_wakeup; | 1511 | sk->sk_state_change = sock_def_wakeup; |
1427 | sk->sk_data_ready = sock_def_readable; | 1512 | sk->sk_data_ready = sock_def_readable; |
@@ -1449,24 +1534,34 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
1449 | void fastcall lock_sock(struct sock *sk) | 1534 | void fastcall lock_sock(struct sock *sk) |
1450 | { | 1535 | { |
1451 | might_sleep(); | 1536 | might_sleep(); |
1452 | spin_lock_bh(&(sk->sk_lock.slock)); | 1537 | spin_lock_bh(&sk->sk_lock.slock); |
1453 | if (sk->sk_lock.owner) | 1538 | if (sk->sk_lock.owner) |
1454 | __lock_sock(sk); | 1539 | __lock_sock(sk); |
1455 | sk->sk_lock.owner = (void *)1; | 1540 | sk->sk_lock.owner = (void *)1; |
1456 | 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(); | ||
1457 | } | 1547 | } |
1458 | 1548 | ||
1459 | EXPORT_SYMBOL(lock_sock); | 1549 | EXPORT_SYMBOL(lock_sock); |
1460 | 1550 | ||
1461 | void fastcall release_sock(struct sock *sk) | 1551 | void fastcall release_sock(struct sock *sk) |
1462 | { | 1552 | { |
1463 | 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); | ||
1464 | if (sk->sk_backlog.tail) | 1559 | if (sk->sk_backlog.tail) |
1465 | __release_sock(sk); | 1560 | __release_sock(sk); |
1466 | sk->sk_lock.owner = NULL; | 1561 | sk->sk_lock.owner = NULL; |
1467 | if (waitqueue_active(&(sk->sk_lock.wq))) | 1562 | if (waitqueue_active(&sk->sk_lock.wq)) |
1468 | wake_up(&(sk->sk_lock.wq)); | 1563 | wake_up(&sk->sk_lock.wq); |
1469 | spin_unlock_bh(&(sk->sk_lock.slock)); | 1564 | spin_unlock_bh(&sk->sk_lock.slock); |
1470 | } | 1565 | } |
1471 | EXPORT_SYMBOL(release_sock); | 1566 | EXPORT_SYMBOL(release_sock); |
1472 | 1567 | ||