aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2011-08-19 09:47:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-24 14:41:44 -0400
commite8753043f9fbabffbf087c7f4b514c50ef89541e (patch)
tree2c4b382a21500c228005a43e48134d39fdcccbe8
parent4e0d8cc1006b889909a87f824943bad9a56358e8 (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.c17
-rw-r--r--include/linux/nfc.h2
-rw-r--r--include/net/nfc.h7
-rw-r--r--net/nfc/core.c6
-rw-r--r--net/nfc/rawsock.c13
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 {
89extern struct class nfc_class; 92extern struct class nfc_class;
90 93
91struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, 94struct 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 */
324struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, 324struct 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
124static int rawsock_add_header(struct sk_buff *skb) 124static 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);