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>
This commit is contained in:
parent
4e0d8cc100
commit
e8753043f9
5 changed files with 22 additions and 23 deletions
|
@ -1246,7 +1246,6 @@ static int pn533_data_exchange_tx_frame(struct pn533 *dev, struct sk_buff *skb)
|
|||
{
|
||||
int payload_len = skb->len;
|
||||
struct pn533_frame *out_frame;
|
||||
struct sk_buff *discarded;
|
||||
u8 tg;
|
||||
|
||||
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)
|
|||
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);
|
||||
out_frame = (struct pn533_frame *) skb->data;
|
||||
|
||||
|
@ -1536,7 +1523,9 @@ static int pn533_probe(struct usb_interface *interface,
|
|||
| NFC_PROTO_ISO14443_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)
|
||||
goto kill_tasklet;
|
||||
|
||||
|
|
|
@ -123,4 +123,6 @@ struct sockaddr_nfc {
|
|||
#define NFC_SOCKPROTO_RAW 0
|
||||
#define NFC_SOCKPROTO_MAX 1
|
||||
|
||||
#define NFC_HEADER_SIZE 1
|
||||
|
||||
#endif /*__LINUX_NFC_H */
|
||||
|
|
|
@ -82,6 +82,9 @@ struct nfc_dev {
|
|||
struct nfc_genl_data genl_data;
|
||||
u32 supported_protocols;
|
||||
|
||||
int tx_headroom;
|
||||
int tx_tailroom;
|
||||
|
||||
struct nfc_ops *ops;
|
||||
};
|
||||
#define to_nfc_dev(_dev) container_of(_dev, struct nfc_dev, dev)
|
||||
|
@ -89,7 +92,9 @@ struct nfc_dev {
|
|||
extern struct class nfc_class;
|
||||
|
||||
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
|
||||
|
|
|
@ -322,7 +322,9 @@ struct nfc_dev *nfc_get_device(unsigned idx)
|
|||
* @supported_protocols: NFC protocols supported by the device
|
||||
*/
|
||||
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);
|
||||
struct nfc_dev *dev;
|
||||
|
@ -345,6 +347,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops,
|
|||
|
||||
dev->ops = ops;
|
||||
dev->supported_protocols = supported_protocols;
|
||||
dev->tx_headroom = tx_headroom;
|
||||
dev->tx_tailroom = tx_tailroom;
|
||||
|
||||
spin_lock_init(&dev->targets_lock);
|
||||
nfc_genl_data_init(&dev->genl_data);
|
||||
|
|
|
@ -123,11 +123,7 @@ static int rawsock_connect(struct socket *sock, struct sockaddr *_addr,
|
|||
|
||||
static int rawsock_add_header(struct sk_buff *skb)
|
||||
{
|
||||
|
||||
if (skb_cow_head(skb, 1))
|
||||
return -ENOMEM;
|
||||
|
||||
*skb_push(skb, 1) = 0;
|
||||
*skb_push(skb, NFC_HEADER_SIZE) = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -197,6 +193,7 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||
struct msghdr *msg, size_t len)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
struct nfc_dev *dev = nfc_rawsock(sk)->dev;
|
||||
struct sk_buff *skb;
|
||||
int rc;
|
||||
|
||||
|
@ -208,11 +205,13 @@ static int rawsock_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|||
if (sock->state != SS_CONNECTED)
|
||||
return -ENOTCONN;
|
||||
|
||||
skb = sock_alloc_send_skb(sk, len, msg->msg_flags & MSG_DONTWAIT,
|
||||
&rc);
|
||||
skb = sock_alloc_send_skb(sk, len + dev->tx_headroom + dev->tx_tailroom + NFC_HEADER_SIZE,
|
||||
msg->msg_flags & MSG_DONTWAIT, &rc);
|
||||
if (!skb)
|
||||
return rc;
|
||||
|
||||
skb_reserve(skb, dev->tx_headroom + NFC_HEADER_SIZE);
|
||||
|
||||
rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
|
||||
if (rc < 0) {
|
||||
kfree_skb(skb);
|
||||
|
|
Loading…
Reference in a new issue