Commit e8753043 authored by Samuel Ortiz's avatar Samuel Ortiz Committed by John W. Linville

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: default avatarSamuel Ortiz <sameo@linux.intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4e0d8cc1
...@@ -1246,7 +1246,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb) ...@@ -1246,7 +1246,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb)
{ {
int payload_len = skb->len; int payload_len = skb->len;
struct pn533_frame *out_frame; struct pn533_frame *out_frame;
struct sk_buff *discarded;
u8 tg; u8 tg;
nfc_dev_dbg(&dev->interface->dev, "%s - Sending %d bytes", __func__, 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,18 +1259,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb)
return -ENOSYS; return -ENOSYS;
} }
/* Reserving header space */
if (skb_cow_head(skb, PN533_CMD_DATAEXCH_HEAD_LEN)) {
nfc_dev_err(&dev->interface->dev, "Error to add header data");
return -ENOMEM;
}
/* Reserving tail space, see pn533_tx_frame_finish */
if (skb_cow_data(skb, PN533_FRAME_TAIL_SIZE, &discarded) < 0) {
nfc_dev_err(&dev->interface->dev, "Error to add tail data");
return -ENOMEM;
}
skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN); skb_push(skb, PN533_CMD_DATAEXCH_HEAD_LEN);
out_frame = (struct pn533_frame *) skb->data; out_frame = (struct pn533_frame *) skb->data;
...@@ -1536,7 +1523,9 @@ static int pn533_probe(struct usb_interface *interface, ...@@ -1536,7 +1523,9 @@ static int pn533_probe(struct usb_interface *interface,
| NFC_PROTO_ISO14443_MASK | NFC_PROTO_ISO14443_MASK
| NFC_PROTO_NFC_DEP_MASK; | NFC_PROTO_NFC_DEP_MASK;
dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols); dev->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
PN533_CMD_DATAEXCH_HEAD_LEN,
PN533_FRAME_TAIL_SIZE);
if (!dev->nfc_dev) if (!dev->nfc_dev)
goto kill_tasklet; goto kill_tasklet;
......
...@@ -123,4 +123,6 @@ struct sockaddr_nfc { ...@@ -123,4 +123,6 @@ struct sockaddr_nfc {
#define NFC_SOCKPROTO_RAW 0 #define NFC_SOCKPROTO_RAW 0
#define NFC_SOCKPROTO_MAX 1 #define NFC_SOCKPROTO_MAX 1
#define NFC_HEADER_SIZE 1
#endif /*__LINUX_NFC_H */ #endif /*__LINUX_NFC_H */
...@@ -82,6 +82,9 @@ struct nfc_dev { ...@@ -82,6 +82,9 @@ struct nfc_dev {
struct nfc_genl_data genl_data; struct nfc_genl_data genl_data;
u32 supported_protocols; u32 supported_protocols;
int tx_headroom;
int tx_tailroom;
struct nfc_ops *ops; struct nfc_ops *ops;
}; };
#define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev) #define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev)
...@@ -89,7 +92,9 @@ struct nfc_dev { ...@@ -89,7 +92,9 @@ struct nfc_dev {
extern struct class nfc_class; extern struct class nfc_class;
struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
u32 supported_protocols); u32 supported_protocols,
int tx_headroom,
int tx_tailroom);
/** /**
* nfc_free_device - free nfc device * nfc_free_device - free nfc device
......
...@@ -322,7 +322,9 @@ struct nfc_dev *nfc_get_device(unsigned idx) ...@@ -322,7 +322,9 @@ struct nfc_dev *nfc_get_device(unsigned idx)
* @supported_protocols: NFC protocols supported by the device * @supported_protocols: NFC protocols supported by the device
*/ */
struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
u32 supported_protocols) u32 supported_protocols,
int tx_headroom,
int tx_tailroom)
{ {
static atomic_t dev_no = ATOMIC_INIT(0); static atomic_t dev_no = ATOMIC_INIT(0);
struct nfc_dev *dev; struct nfc_dev *dev;
...@@ -345,6 +347,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, ...@@ -345,6 +347,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
dev->ops = ops; dev->ops = ops;
dev->supported_protocols = supported_protocols; dev->supported_protocols = supported_protocols;
dev->tx_headroom = tx_headroom;
dev->tx_tailroom = tx_tailroom;
spin_lock_init(&dev->targets_lock); spin_lock_init(&dev->targets_lock);
nfc_genl_data_init(&dev->genl_data); nfc_genl_data_init(&dev->genl_data);
......
...@@ -123,11 +123,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr, ...@@ -123,11 +123,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
static int rawsock_add_header(struct sk_buff *skb) static int rawsock_add_header(struct sk_buff *skb)
{ {
*skb_push(skb, NFC_HEADER_SIZE) = 0;
if (skb_cow_head(skb, 1))
return -ENOMEM;
*skb_push(skb, 1) = 0;
return 0; return 0;
} }
...@@ -197,6 +193,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -197,6 +193,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct nfc_dev *dev = nfc_rawsock(sk)->dev;
struct sk_buff *skb; struct sk_buff *skb;
int rc; int rc;
...@@ -208,11 +205,13 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -208,11 +205,13 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (sock->state != SS_CONNECTED) if (sock->state != SS_CONNECTED)
return -ENOTCONN; return -ENOTCONN;
skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT, skb = sock_alloc_send_skb(sk, len + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE,
&rc); msg->msg_flags & MSG_DONTWAIT, &rc);
if (!skb) if (!skb)
return rc; return rc;
skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
if (rc < 0) { if (rc < 0) {
kfree_skb(skb); kfree_skb(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment