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

Bluetooth: Split sending for HCI raw and control sockets

The sending functions for HCI raw and control sockets have nothing in
common except that they iterate over the socket list. Split them into
two so they can do their job more efficient. In addition the code becomes
more readable.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>

authored by

Marcel Holtmann and committed by
Johan Hedberg
470fe1b5 48c7aba9

+45 -18
+2 -2
include/net/bluetooth/hci_core.h
··· 953 953 void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); 954 954 955 955 /* ----- HCI Sockets ----- */ 956 - void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, 957 - struct sock *skip_sk); 956 + void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); 957 + void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); 958 958 959 959 /* Management interface */ 960 960 #define MGMT_ADDR_BREDR 0x00
+2 -2
net/bluetooth/hci_core.c
··· 2131 2131 /* Time stamp */ 2132 2132 __net_timestamp(skb); 2133 2133 2134 - hci_send_to_sock(hdev, skb, NULL); 2134 + hci_send_to_sock(hdev, skb); 2135 2135 } 2136 2136 2137 2137 /* Get rid of skb owner, prior to sending to the driver. */ ··· 2818 2818 while ((skb = skb_dequeue(&hdev->rx_q))) { 2819 2819 if (atomic_read(&hdev->promisc)) { 2820 2820 /* Send copy to the sockets */ 2821 - hci_send_to_sock(hdev, skb, NULL); 2821 + hci_send_to_sock(hdev, skb); 2822 2822 } 2823 2823 2824 2824 if (test_bit(HCI_RAW, &hdev->flags)) {
+1 -1
net/bluetooth/hci_event.c
··· 3571 3571 3572 3572 bt_cb(skb)->pkt_type = HCI_EVENT_PKT; 3573 3573 skb->dev = (void *) hdev; 3574 - hci_send_to_sock(hdev, skb, NULL); 3574 + hci_send_to_sock(hdev, skb); 3575 3575 kfree_skb(skb); 3576 3576 } 3577 3577
+39 -12
net/bluetooth/hci_sock.c
··· 85 85 }; 86 86 87 87 /* Send frame to RAW socket */ 88 - void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, 89 - struct sock *skip_sk) 88 + void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) 90 89 { 91 90 struct sock *sk; 92 91 struct hlist_node *node; ··· 93 94 BT_DBG("hdev %p len %d", hdev, skb->len); 94 95 95 96 read_lock(&hci_sk_list.lock); 97 + 96 98 sk_for_each(sk, node, &hci_sk_list.head) { 97 99 struct hci_filter *flt; 98 100 struct sk_buff *nskb; 99 - 100 - if (sk == skip_sk) 101 - continue; 102 101 103 102 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev) 104 103 continue; ··· 105 108 if (skb->sk == sk) 106 109 continue; 107 110 108 - if (bt_cb(skb)->channel != hci_pi(sk)->channel) 111 + if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) 109 112 continue; 110 - 111 - if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL) 112 - goto clone; 113 113 114 114 /* Apply filter */ 115 115 flt = &hci_pi(sk)->filter; ··· 131 137 continue; 132 138 } 133 139 134 - clone: 135 140 nskb = skb_clone(skb, GFP_ATOMIC); 136 141 if (!nskb) 137 142 continue; 138 143 139 144 /* Put type byte before the data */ 140 - if (bt_cb(skb)->channel == HCI_CHANNEL_RAW) 141 - memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); 145 + memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); 142 146 143 147 if (sock_queue_rcv_skb(sk, nskb)) 144 148 kfree_skb(nskb); 145 149 } 150 + 151 + read_unlock(&hci_sk_list.lock); 152 + } 153 + 154 + /* Send frame to control socket */ 155 + void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk) 156 + { 157 + struct sock *sk; 158 + struct hlist_node *node; 159 + 160 + BT_DBG("len %d", skb->len); 161 + 162 + read_lock(&hci_sk_list.lock); 163 + 164 + sk_for_each(sk, node, &hci_sk_list.head) { 165 + struct sk_buff *nskb; 166 + 167 + /* Skip the original socket */ 168 + if (sk == skip_sk) 169 + continue; 170 + 171 + if (sk->sk_state != BT_BOUND) 172 + continue; 173 + 174 + if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL) 175 + continue; 176 + 177 + nskb = skb_clone(skb, GFP_ATOMIC); 178 + if (!nskb) 179 + continue; 180 + 181 + if (sock_queue_rcv_skb(sk, nskb)) 182 + kfree_skb(nskb); 183 + } 184 + 146 185 read_unlock(&hci_sk_list.lock); 147 186 } 148 187
+1 -1
net/bluetooth/mgmt.c
··· 924 924 if (data) 925 925 memcpy(skb_put(skb, data_len), data, data_len); 926 926 927 - hci_send_to_sock(NULL, skb, skip_sk); 927 + hci_send_to_control(skb, skip_sk); 928 928 kfree_skb(skb); 929 929 930 930 return 0;