diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2011-08-19 09:47:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-24 14:41:44 -0400 |
commit | e8753043f9fbabffbf087c7f4b514c50ef89541e (patch) | |
tree | 2c4b382a21500c228005a43e48134d39fdcccbe8 | |
parent | 4e0d8cc1006b889909a87f824943bad9a56358e8 (diff) |
NFC: Reserve tx head and tail room
We can have the NFC core layer allocating the tx head and tail
room for the drivers and avoid 1 or more SKBs copy on write on
the Tx path.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/nfc/pn533.c | 17 | ||||
-rw-r--r-- | include/linux/nfc.h | 2 | ||||
-rw-r--r-- | include/net/nfc.h | 7 | ||||
-rw-r--r-- | net/nfc/core.c | 6 | ||||
-rw-r--r-- | net/nfc/rawsock.c | 13 |
5 files changed, 22 insertions, 23 deletions
diff --git a/drivers/nfc/pn533.c b/drivers/nfc/pn533.c index c77e0543e502..f81a93e5b59d 100644 --- a/drivers/nfc/pn533.c +++ b/drivers/nfc/pn533.c | |||
@@ -1246,7 +1246,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) | |||
1246 | { | 1246 | { |
1247 | int payload_len = skb->len; | 1247 | int payload_len = skb->len; |
1248 | struct pn533_frame *out_frame; | 1248 | struct pn533_frame *out_frame; |
1249 | struct sk_buff *discarded; | ||
1250 | u8 tg; | 1249 | u8 tg; |
1251 | 1250 | ||
1252 | nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__, | 1251 | nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__, |
@@ -1260,18 +1259,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) | |||
1260 | return -ENOSYS; | 1259 | return -ENOSYS; |
1261 | } | 1260 | } |
1262 | 1261 | ||
1263 | /* Reserving header space */ | ||
1264 | if (skb_cow_head(skb, PN533_CMD_DATAEXCH_HEAD_LEN)) { | ||
1265 | nfc_dev_err(&dev->interface->dev, "Error to add header data"); | ||
1266 | return -ENOMEM; | ||
1267 | } | ||
1268 | |||
1269 | /* Reserving tail space, see pn533_tx_frame_finish */ | ||
1270 | if (skb_cow_data(skb, PN533_FRAME_TAIL_SIZE, &discarded) < 0) { | ||
1271 | nfc_dev_err(&dev->interface->dev, "Error to add tail data"); | ||
1272 | return -ENOMEM; | ||
1273 | } | ||
1274 | |||
1275 | skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); | 1262 | skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); |
1276 | out_frame = (struct pn533_frame *) skb->data; | 1263 | out_frame = (struct pn533_frame *) skb->data; |
1277 | 1264 | ||
@@ -1536,7 +1523,9 @@ static int pn533_probe(struct usb_interface *interface, | |||
1536 | | NFC_PROTO_ISO14443_MASK | 1523 | | NFC_PROTO_ISO14443_MASK |
1537 | | NFC_PROTO_NFC_DEP_MASK; | 1524 | | NFC_PROTO_NFC_DEP_MASK; |
1538 | 1525 | ||
1539 | dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols); | 1526 | dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols, |
1527 | PN533_CMD_DATAEXCH_HEAD_LEN, | ||
1528 | PN533_FRAME_TAIL_SIZE); | ||
1540 | if (!dev->nfc_dev) | 1529 | if (!dev->nfc_dev) |
1541 | goto kill_tasklet; | 1530 | goto kill_tasklet; |
1542 | 1531 | ||
diff --git a/include/linux/nfc.h b/include/linux/nfc.h index 330a4c5db588..c525e0b5876b 100644 --- a/include/linux/nfc.h +++ b/include/linux/nfc.h | |||
@@ -123,4 +123,6 @@ struct sockaddr_nfc { | |||
123 | #define NFC_SOCKPROTO_RAW 0 | 123 | #define NFC_SOCKPROTO_RAW 0 |
124 | #define NFC_SOCKPROTO_MAX 1 | 124 | #define NFC_SOCKPROTO_MAX 1 |
125 | 125 | ||
126 | #define NFC_HEADER_SIZE 1 | ||
127 | |||
126 | #endif /*__LINUX_NFC_H */ | 128 | #endif /*__LINUX_NFC_H */ |
diff --git a/include/net/nfc.h b/include/net/nfc.h index cc0130312f70..87b51fe15b70 100644 --- a/include/net/nfc.h +++ b/include/net/nfc.h | |||
@@ -82,6 +82,9 @@ struct nfc_dev { | |||
82 | struct nfc_genl_data genl_data; | 82 | struct nfc_genl_data genl_data; |
83 | u32 supported_protocols; | 83 | u32 supported_protocols; |
84 | 84 | ||
85 | int tx_headroom; | ||
86 | int tx_tailroom; | ||
87 | |||
85 | struct nfc_ops *ops; | 88 | struct nfc_ops *ops; |
86 | }; | 89 | }; |
87 | #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) | 90 | #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) |
@@ -89,7 +92,9 @@ struct nfc_dev { | |||
89 | extern struct class nfc_class; | 92 | extern struct class nfc_class; |
90 | 93 | ||
91 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 94 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, |
92 | u32 supported_protocols); | 95 | u32 supported_protocols, |
96 | int tx_headroom, | ||
97 | int tx_tailroom); | ||
93 | 98 | ||
94 | /** | 99 | /** |
95 | * nfc_free_device - free nfc device | 100 | * nfc_free_device - free nfc device |
diff --git a/net/nfc/core.c b/net/nfc/core.c index b6fd4e1f2057..284e2f6a14ff 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -322,7 +322,9 @@ struct nfc_dev *nfc_get_device(unsigned idx) | |||
322 | * @supported_protocols: NFC protocols supported by the device | 322 | * @supported_protocols: NFC protocols supported by the device |
323 | */ | 323 | */ |
324 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 324 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, |
325 | u32 supported_protocols) | 325 | u32 supported_protocols, |
326 | int tx_headroom, | ||
327 | int tx_tailroom) | ||
326 | { | 328 | { |
327 | static atomic_t dev_no = ATOMIC_INIT(0); | 329 | static atomic_t dev_no = ATOMIC_INIT(0); |
328 | struct nfc_dev *dev; | 330 | struct nfc_dev *dev; |
@@ -345,6 +347,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | |||
345 | 347 | ||
346 | dev->ops = ops; | 348 | dev->ops = ops; |
347 | dev->supported_protocols = supported_protocols; | 349 | dev->supported_protocols = supported_protocols; |
350 | dev->tx_headroom = tx_headroom; | ||
351 | dev->tx_tailroom = tx_tailroom; | ||
348 | 352 | ||
349 | spin_lock_init(&dev->targets_lock); | 353 | spin_lock_init(&dev->targets_lock); |
350 | nfc_genl_data_init(&dev->genl_data); | 354 | nfc_genl_data_init(&dev->genl_data); |
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index 52de84a55115..9fd652a51424 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c | |||
@@ -123,11 +123,7 @@ error: | |||
123 | 123 | ||
124 | static int rawsock_add_header(struct sk_buff *skb) | 124 | static int rawsock_add_header(struct sk_buff *skb) |
125 | { | 125 | { |
126 | 126 | *skb_push(skb, NFC_HEADER_SIZE) = 0; | |
127 | if (skb_cow_head(skb, 1)) | ||
128 | return -ENOMEM; | ||
129 | |||
130 | *skb_push(skb, 1) = 0; | ||
131 | 127 | ||
132 | return 0; | 128 | return 0; |
133 | } | 129 | } |
@@ -197,6 +193,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
197 | struct msghdr *msg, size_t len) | 193 | struct msghdr *msg, size_t len) |
198 | { | 194 | { |
199 | struct sock *sk = sock->sk; | 195 | struct sock *sk = sock->sk; |
196 | struct nfc_dev *dev = nfc_rawsock(sk)->dev; | ||
200 | struct sk_buff *skb; | 197 | struct sk_buff *skb; |
201 | int rc; | 198 | int rc; |
202 | 199 | ||
@@ -208,11 +205,13 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
208 | if (sock->state != SS_CONNECTED) | 205 | if (sock->state != SS_CONNECTED) |
209 | return -ENOTCONN; | 206 | return -ENOTCONN; |
210 | 207 | ||
211 | skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, | 208 | skb = sock_alloc_send_skb(sk, len + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE, |
212 | &rc); | 209 | msg->msg_flags & MSG_DONTWAIT, &rc); |
213 | if (!skb) | 210 | if (!skb) |
214 | return rc; | 211 | return rc; |
215 | 212 | ||
213 | skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE); | ||
214 | |||
216 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | 215 | rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); |
217 | if (rc < 0) { | 216 | if (rc < 0) { |
218 | kfree_skb(skb); | 217 | kfree_skb(skb); |