Skip to content

Commit

Permalink
NFC: Reserve tx head and tail room
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Samuel Ortiz authored and John W. Linville committed Aug 24, 2011
1 parent 4e0d8cc commit e875304
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 23 deletions.
17 changes: 3 additions & 14 deletions drivers/nfc/pn533.c
Original file line number Diff line number Diff line change
Expand Up @@ -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__,
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions include/linux/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
7 changes: 6 additions & 1 deletion include/net/nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,19 @@ 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)

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
Expand Down
6 changes: 5 additions & 1 deletion net/nfc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
13 changes: 6 additions & 7 deletions net/nfc/rawsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand All @@ -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);
Expand Down

0 comments on commit e875304

Please sign in to comment.