* [PATCH 05/28] fs: introduce new ->get_poll_head and ->poll_mask methods
From: Christoph Hellwig @ 2018-03-21 7:40 UTC (permalink / raw)
To: viro; +Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180321074032.14211-1-hch@lst.de>
->get_poll_head returns the waitqueue that the poll operation is going
to sleep on. Note that this means we can only use a single waitqueue
for the poll, unlike some current drivers that use two waitqueues for
different events. But now that we have keyed wakeups and heavily use
those for poll there aren't that many good reason left to keep the
multiple waitqueues, and if there are any ->poll is still around, the
driver just won't support aio poll.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
Documentation/filesystems/Locking | 7 ++++++-
Documentation/filesystems/vfs.txt | 13 +++++++++++++
fs/select.c | 28 ++++++++++++++++++++++++++++
include/linux/fs.h | 2 ++
include/linux/poll.h | 27 +++++++++++++++++++++++----
5 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 220bba28f72b..6d227f9d7bd9 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -440,6 +440,8 @@ prototypes:
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
__poll_t (*poll) (struct file *, struct poll_table_struct *);
+ struct wait_queue_head * (*get_poll_head)(struct file *, __poll_t);
+ __poll_t (*poll_mask) (struct file *, __poll_t);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
@@ -470,7 +472,7 @@ prototypes:
};
locking rules:
- All may block.
+ All except for ->poll_mask may block.
->llseek() locking has moved from llseek to the individual llseek
implementations. If your fs is not using generic_file_llseek, you
@@ -498,6 +500,9 @@ in sys_read() and friends.
the lease within the individual filesystem to record the result of the
operation
+->poll_mask can be called with or without the waitqueue lock for the waitqueue
+returned from ->get_poll_head.
+
--------------------------- dquot_operations -------------------------------
prototypes:
int (*write_dquot) (struct dquot *);
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index f608180ad59d..50ee13563271 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -857,6 +857,8 @@ struct file_operations {
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
__poll_t (*poll) (struct file *, struct poll_table_struct *);
+ struct wait_queue_head * (*get_poll_head)(struct file *, __poll_t);
+ __poll_t (*poll_mask) (struct file *, __poll_t);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
@@ -901,6 +903,17 @@ otherwise noted.
activity on this file and (optionally) go to sleep until there
is activity. Called by the select(2) and poll(2) system calls
+ get_poll_head: Returns the struct wait_queue_head that poll, select,
+ epoll or aio poll should wait on in case this instance only has single
+ waitqueue. Can return NULL to indicate polling is not supported,
+ or a POLL* value using the POLL_TO_PTR helper in case a grave error
+ occured and ->poll_mask shall not be called.
+
+ poll_mask: return the mask of POLL* values describing the file descriptor
+ state. Called either before going to sleep on the waitqueue returned by
+ get_poll_head, or after it has been woken. If ->get_poll_head and
+ ->poll_mask are implemented ->poll does not need to be implement.
+
unlocked_ioctl: called by the ioctl(2) system call.
compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
diff --git a/fs/select.c b/fs/select.c
index ba91103707ea..cc270d7f6192 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -34,6 +34,34 @@
#include <linux/uaccess.h>
+__poll_t vfs_poll(struct file *file, struct poll_table_struct *pt)
+{
+ unsigned int events = poll_requested_events(pt);
+ struct wait_queue_head *head;
+
+ if (unlikely(!file_can_poll(file)))
+ return DEFAULT_POLLMASK;
+
+ if (file->f_op->poll)
+ return file->f_op->poll(file, pt);
+
+ /*
+ * Only get the poll head and do the first mask check if we are actually
+ * going to sleep on this file:
+ */
+ if (pt && pt->_qproc) {
+ head = vfs_get_poll_head(file, events);
+ if (!head)
+ return DEFAULT_POLLMASK;
+ if (IS_ERR(head))
+ return PTR_TO_POLL(head);
+
+ pt->_qproc(file, head, pt);
+ }
+
+ return file->f_op->poll_mask(file, events);
+}
+EXPORT_SYMBOL_GPL(vfs_poll);
/*
* Estimate expected accuracy in ns from a timeval.
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 79c413985305..6ea2c0843bb1 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1708,6 +1708,8 @@ struct file_operations {
int (*iterate) (struct file *, struct dir_context *);
int (*iterate_shared) (struct file *, struct dir_context *);
__poll_t (*poll) (struct file *, struct poll_table_struct *);
+ struct wait_queue_head * (*get_poll_head)(struct file *, __poll_t);
+ __poll_t (*poll_mask) (struct file *, __poll_t);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
diff --git a/include/linux/poll.h b/include/linux/poll.h
index 7e0fdcf905d2..42e8e8665fb0 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -74,18 +74,37 @@ static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
pt->_key = ~(__poll_t)0; /* all events enabled */
}
+/*
+ * ->get_poll_head can return a __poll_t in the PTR_ERR, use these macros
+ * to return the value and recover it. It takes care of the negation as
+ * well as off the annotations.
+ */
+#define POLL_TO_PTR(mask) (ERR_PTR(-(__force int)(mask)))
+#define PTR_TO_POLL(ptr) ((__force __poll_t)-PTR_ERR((ptr)))
+
static inline bool file_can_poll(struct file *file)
{
- return file->f_op->poll;
+ return file->f_op->poll ||
+ (file->f_op->get_poll_head && file->f_op->poll_mask);
}
-static inline __poll_t vfs_poll(struct file *file, struct poll_table_struct *pt)
+static inline struct wait_queue_head *vfs_get_poll_head(struct file *file,
+ __poll_t events)
{
- if (unlikely(!file->f_op->poll))
+ if (unlikely(!file->f_op->get_poll_head || !file->f_op->poll_mask))
+ return NULL;
+ return file->f_op->get_poll_head(file, events);
+}
+
+static inline __poll_t vfs_poll_mask(struct file *file, __poll_t events)
+{
+ if (unlikely(!file->f_op->poll_mask))
return DEFAULT_POLLMASK;
- return file->f_op->poll(file, pt);
+ return file->f_op->poll_mask(file, events) & events;
}
+__poll_t vfs_poll(struct file *file, struct poll_table_struct *pt);
+
struct poll_table_entry {
struct file *filp;
__poll_t key;
--
2.14.2
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH 04/28] fs: add new vfs_poll and file_can_poll helpers
From: Christoph Hellwig @ 2018-03-21 7:40 UTC (permalink / raw)
To: viro; +Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180321074032.14211-1-hch@lst.de>
These abstract out calls to the poll method in preparation for changes
in how we poll.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
drivers/staging/comedi/drivers/serial2002.c | 4 ++--
drivers/vfio/virqfd.c | 2 +-
drivers/vhost/vhost.c | 2 +-
fs/eventpoll.c | 5 ++---
fs/select.c | 23 ++++++++---------------
include/linux/poll.h | 12 ++++++++++++
mm/memcontrol.c | 2 +-
net/9p/trans_fd.c | 18 ++++--------------
virt/kvm/eventfd.c | 2 +-
9 files changed, 32 insertions(+), 38 deletions(-)
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index b3f3b4a201af..5471b2212a62 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -113,7 +113,7 @@ static void serial2002_tty_read_poll_wait(struct file *f, int timeout)
long elapsed;
__poll_t mask;
- mask = f->f_op->poll(f, &table.pt);
+ mask = vfs_poll(f, &table.pt);
if (mask & (EPOLLRDNORM | EPOLLRDBAND | EPOLLIN |
EPOLLHUP | EPOLLERR)) {
break;
@@ -136,7 +136,7 @@ static int serial2002_tty_read(struct file *f, int timeout)
result = -1;
if (!IS_ERR(f)) {
- if (f->f_op->poll) {
+ if (file_can_poll(f)) {
serial2002_tty_read_poll_wait(f, timeout);
if (kernel_read(f, &ch, 1, &pos) == 1)
diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c
index 085700f1be10..2a1be859ee71 100644
--- a/drivers/vfio/virqfd.c
+++ b/drivers/vfio/virqfd.c
@@ -166,7 +166,7 @@ int vfio_virqfd_enable(void *opaque,
init_waitqueue_func_entry(&virqfd->wait, virqfd_wakeup);
init_poll_funcptr(&virqfd->pt, virqfd_ptable_queue_proc);
- events = irqfd.file->f_op->poll(irqfd.file, &virqfd->pt);
+ events = vfs_poll(irqfd.file, &virqfd->pt);
/*
* Check if there was an event already pending on the eventfd
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 1b3e8d2d5c8b..4d27e288bb1d 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -208,7 +208,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
if (poll->wqh)
return 0;
- mask = file->f_op->poll(file, &poll->table);
+ mask = vfs_poll(file, &poll->table);
if (mask)
vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
if (mask & EPOLLERR) {
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 0f3494ed3ed0..2bebae5a38cf 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -884,8 +884,7 @@ static __poll_t ep_item_poll(const struct epitem *epi, poll_table *pt,
pt->_key = epi->event.events;
if (!is_file_epoll(epi->ffd.file))
- return epi->ffd.file->f_op->poll(epi->ffd.file, pt) &
- epi->event.events;
+ return vfs_poll(epi->ffd.file, pt) & epi->event.events;
ep = epi->ffd.file->private_data;
poll_wait(epi->ffd.file, &ep->poll_wait, pt);
@@ -2020,7 +2019,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
/* The target file descriptor must support poll */
error = -EPERM;
- if (!tf.file->f_op->poll)
+ if (!file_can_poll(tf.file))
goto error_tgt_fput;
/* Check if EPOLLWAKEUP is allowed */
diff --git a/fs/select.c b/fs/select.c
index c6c504a814f9..ba91103707ea 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -502,14 +502,10 @@ static int do_select(int n, fd_set_bits *fds, struct timespec64 *end_time)
continue;
f = fdget(i);
if (f.file) {
- const struct file_operations *f_op;
- f_op = f.file->f_op;
- mask = DEFAULT_POLLMASK;
- if (f_op->poll) {
- wait_key_set(wait, in, out,
- bit, busy_flag);
- mask = (*f_op->poll)(f.file, wait);
- }
+ wait_key_set(wait, in, out, bit,
+ busy_flag);
+ mask = vfs_poll(f.file, wait);
+
fdput(f);
if ((mask & POLLIN_SET) && (in & bit)) {
res_in |= bit;
@@ -819,13 +815,10 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
/* userland u16 ->events contains POLL... bitmap */
filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
- mask = DEFAULT_POLLMASK;
- if (f.file->f_op->poll) {
- pwait->_key = filter | busy_flag;
- mask = f.file->f_op->poll(f.file, pwait);
- if (mask & busy_flag)
- *can_busy_poll = true;
- }
+ pwait->_key = filter | busy_flag;
+ mask = vfs_poll(f.file, pwait);
+ if (mask & busy_flag)
+ *can_busy_poll = true;
mask &= filter; /* Mask out unneeded events. */
fdput(f);
diff --git a/include/linux/poll.h b/include/linux/poll.h
index a3576da63377..7e0fdcf905d2 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -74,6 +74,18 @@ static inline void init_poll_funcptr(poll_table *pt, poll_queue_proc qproc)
pt->_key = ~(__poll_t)0; /* all events enabled */
}
+static inline bool file_can_poll(struct file *file)
+{
+ return file->f_op->poll;
+}
+
+static inline __poll_t vfs_poll(struct file *file, struct poll_table_struct *pt)
+{
+ if (unlikely(!file->f_op->poll))
+ return DEFAULT_POLLMASK;
+ return file->f_op->poll(file, pt);
+}
+
struct poll_table_entry {
struct file *filp;
__poll_t key;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 670e99b68aa6..8774ece5c3c3 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -3849,7 +3849,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
if (ret)
goto out_put_css;
- efile.file->f_op->poll(efile.file, &event->pt);
+ vfs_poll(efile.file, &event->pt);
spin_lock(&memcg->event_list_lock);
list_add(&event->list, &memcg->event_list);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 0cfba919d167..3811775692d0 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -231,7 +231,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
static __poll_t
p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
{
- __poll_t ret, n;
+ __poll_t ret;
struct p9_trans_fd *ts = NULL;
if (client && client->status == Connected)
@@ -243,19 +243,9 @@ p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt, int *err)
return EPOLLERR;
}
- if (!ts->rd->f_op->poll)
- ret = DEFAULT_POLLMASK;
- else
- ret = ts->rd->f_op->poll(ts->rd, pt);
-
- if (ts->rd != ts->wr) {
- if (!ts->wr->f_op->poll)
- n = DEFAULT_POLLMASK;
- else
- n = ts->wr->f_op->poll(ts->wr, pt);
- ret = (ret & ~EPOLLOUT) | (n & ~EPOLLIN);
- }
-
+ ret = vfs_poll(ts->rd, pt);
+ if (ts->rd != ts->wr)
+ ret = (ret & ~EPOLLOUT) | (vfs_poll(ts->wr, pt) & ~EPOLLIN);
return ret;
}
diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c
index 6e865e8b5b10..90d30fbe95ae 100644
--- a/virt/kvm/eventfd.c
+++ b/virt/kvm/eventfd.c
@@ -397,7 +397,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
* Check if there was an event already pending on the eventfd
* before we registered, and trigger it as if we didn't miss it.
*/
- events = f.file->f_op->poll(f.file, &irqfd->pt);
+ events = vfs_poll(f.file, &irqfd->pt);
if (events & EPOLLIN)
schedule_work(&irqfd->inject);
--
2.14.2
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH 03/28] fs: update documentation to mention __poll_t
From: Christoph Hellwig @ 2018-03-21 7:40 UTC (permalink / raw)
To: viro; +Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180321074032.14211-1-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
Documentation/filesystems/Locking | 2 +-
Documentation/filesystems/vfs.txt | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 75d2d57e2c44..220bba28f72b 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -439,7 +439,7 @@ prototypes:
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
- unsigned int (*poll) (struct file *, struct poll_table_struct *);
+ __poll_t (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 5fd325df59e2..f608180ad59d 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -856,7 +856,7 @@ struct file_operations {
ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
int (*iterate) (struct file *, struct dir_context *);
- unsigned int (*poll) (struct file *, struct poll_table_struct *);
+ __poll_t (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
--
2.14.2
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH 02/28] fs: cleanup do_pollfd
From: Christoph Hellwig @ 2018-03-21 7:40 UTC (permalink / raw)
To: viro; +Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180321074032.14211-1-hch@lst.de>
Use straigline code with failure handling gotos instead of a lot
of nested conditionals.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/select.c | 48 +++++++++++++++++++++++-------------------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/fs/select.c b/fs/select.c
index 686de7b3a1db..c6c504a814f9 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -806,34 +806,32 @@ static inline __poll_t do_pollfd(struct pollfd *pollfd, poll_table *pwait,
bool *can_busy_poll,
__poll_t busy_flag)
{
- __poll_t mask;
- int fd;
-
- mask = 0;
- fd = pollfd->fd;
- if (fd >= 0) {
- struct fd f = fdget(fd);
- mask = EPOLLNVAL;
- if (f.file) {
- /* userland u16 ->events contains POLL... bitmap */
- __poll_t filter = demangle_poll(pollfd->events) |
- EPOLLERR | EPOLLHUP;
- mask = DEFAULT_POLLMASK;
- if (f.file->f_op->poll) {
- pwait->_key = filter;
- pwait->_key |= busy_flag;
- mask = f.file->f_op->poll(f.file, pwait);
- if (mask & busy_flag)
- *can_busy_poll = true;
- }
- /* Mask out unneeded events. */
- mask &= filter;
- fdput(f);
- }
+ int fd = pollfd->fd;
+ __poll_t mask = 0, filter;
+ struct fd f;
+
+ if (fd < 0)
+ goto out;
+ mask = EPOLLNVAL;
+ f = fdget(fd);
+ if (!f.file)
+ goto out;
+
+ /* userland u16 ->events contains POLL... bitmap */
+ filter = demangle_poll(pollfd->events) | EPOLLERR | EPOLLHUP;
+ mask = DEFAULT_POLLMASK;
+ if (f.file->f_op->poll) {
+ pwait->_key = filter | busy_flag;
+ mask = f.file->f_op->poll(f.file, pwait);
+ if (mask & busy_flag)
+ *can_busy_poll = true;
}
+ mask &= filter; /* Mask out unneeded events. */
+ fdput(f);
+
+out:
/* ... and so does ->revents */
pollfd->revents = mangle_poll(mask);
-
return mask;
}
--
2.14.2
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* [PATCH 01/28] fs: unexport poll_schedule_timeout
From: Christoph Hellwig @ 2018-03-21 7:40 UTC (permalink / raw)
To: viro; +Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
In-Reply-To: <20180321074032.14211-1-hch@lst.de>
No users outside of select.c.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
fs/select.c | 3 +--
include/linux/poll.h | 2 --
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/fs/select.c b/fs/select.c
index b6c36254028a..686de7b3a1db 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -233,7 +233,7 @@ static void __pollwait(struct file *filp, wait_queue_head_t *wait_address,
add_wait_queue(wait_address, &entry->wait);
}
-int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
+static int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
ktime_t *expires, unsigned long slack)
{
int rc = -EINTR;
@@ -258,7 +258,6 @@ int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
return rc;
}
-EXPORT_SYMBOL(poll_schedule_timeout);
/**
* poll_select_set_timeout - helper function to setup the timeout value
diff --git a/include/linux/poll.h b/include/linux/poll.h
index f45ebd017eaa..a3576da63377 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -96,8 +96,6 @@ struct poll_wqueues {
extern void poll_initwait(struct poll_wqueues *pwq);
extern void poll_freewait(struct poll_wqueues *pwq);
-extern int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
- ktime_t *expires, unsigned long slack);
extern u64 select_estimate_accuracy(struct timespec64 *tv);
#define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1)
--
2.14.2
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply related
* aio poll and a new in-kernel poll API V6
From: Christoph Hellwig @ 2018-03-21 7:40 UTC (permalink / raw)
To: viro; +Cc: Avi Kivity, linux-aio, linux-fsdevel, netdev, linux-api,
linux-kernel
Hi all,
this series adds support for the IOCB_CMD_POLL operation to poll for the
readyness of file descriptors using the aio subsystem. The API is based
on patches that existed in RHAS2.1 and RHEL3, which means it already is
supported by libaio. To implement the poll support efficiently new
methods to poll are introduced in struct file_operations: get_poll_head
and poll_mask. The first one returns a wait_queue_head to wait on
(lifetime is bound by the file), and the second does a non-blocking
check for the POLL* events. This allows aio poll to work without
any additional context switches, unlike epoll.
This series sits on top of the aio-fsync series that also includes
support for io_pgetevents.
The changes were sponsored by Scylladb, and improve performance
of the seastar framework up to 10%, while also removing the need
for a privileged SCHED_FIFO epoll listener thread.
git://git.infradead.org/users/hch/vfs.git aio-poll.6
Gitweb:
http://git.infradead.org/users/hch/vfs.git/shortlog/refs/heads/aio-poll.6
Libaio changes:
https://pagure.io/libaio.git io-poll
Seastar changes (not updated for the new io_pgetevens ABI yet):
https://github.com/avikivity/seastar/commits/aio
Changes since V6:
- small changelog updates
- rebased on top of the aio-fsync changes
Changes since V4:
- rebased ontop of Linux 4.16-rc4
Changes since V3:
- remove the pre-sleep ->poll_mask call in vfs_poll,
allow ->get_poll_head to return POLL* values.
Changes since V2:
- removed a double initialization
- new vfs_get_poll_head helper
- document that ->get_poll_head can return NULL
- call ->poll_mask before sleeping
- various ACKs
- add conversion of random to ->poll_mask
- add conversion of af_alg to ->poll_mask
- lacking ->poll_mask support now returns -EINVAL for IOCB_CMD_POLL
- reshuffled the series so that prep patches and everything not
requiring the new in-kernel poll API is in the beginning
Changes since V1:
- handle the NULL ->poll case in vfs_poll
- dropped the file argument to the ->poll_mask socket operation
- replace the ->pre_poll socket operation with ->get_poll_head as
in the file operations
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH RFC 2/2] virtio_ring: support packed ring
From: Tiwei Bie @ 2018-03-21 7:35 UTC (permalink / raw)
To: Michael S. Tsirkin; +Cc: netdev, linux-kernel, virtualization, wexu
In-Reply-To: <20180316145702-mutt-send-email-mst@kernel.org>
On Fri, Mar 16, 2018 at 04:30:02PM +0200, Michael S. Tsirkin wrote:
> On Fri, Mar 16, 2018 at 07:36:47PM +0800, Jason Wang wrote:
> > > > @@ -1096,17 +1599,21 @@ struct virtqueue *vring_create_virtqueue(
> > > > > > > > > if (!queue) {
> > > > > > > > > /* Try to get a single page. You are my only hope! */
> > > > > > > > > - queue = vring_alloc_queue(vdev, vring_size(num, vring_align),
> > > > > > > > > + queue = vring_alloc_queue(vdev, __vring_size(num, vring_align,
> > > > > > > > > + packed),
> > > > > > > > > &dma_addr, GFP_KERNEL|__GFP_ZERO);
> > > > > > > > > }
> > > > > > > > > if (!queue)
> > > > > > > > > return NULL;
> > > > > > > > > - queue_size_in_bytes = vring_size(num, vring_align);
> > > > > > > > > - vring_init(&vring, num, queue, vring_align);
> > > > > > > > > + queue_size_in_bytes = __vring_size(num, vring_align, packed);
> > > > > > > > > + if (packed)
> > > > > > > > > + vring_packed_init(&vring.vring_packed, num, queue, vring_align);
> > > > > > > > > + else
> > > > > > > > > + vring_init(&vring.vring_split, num, queue, vring_align);
> > > > > > > > Let's rename vring_init to vring_init_split() like other helpers?
> > > > > > > The vring_init() is a public API in include/uapi/linux/virtio_ring.h.
> > > > > > > I don't think we can rename it.
> > > > > > I see, then this need more thoughts to unify the API.
> > > > > My thought is to keep the old API as is, and introduce
> > > > > new types and helpers for packed ring.
> > > > I admit it's not a fault of this patch. But we'd better think of this in the
> > > > future, consider we may have new kinds of ring.
> > > >
> > > > > More details can be found in this patch:
> > > > > https://lkml.org/lkml/2018/2/23/243
> > > > > (PS. The type which has bit fields is just for reference,
> > > > > and will be changed in next version.)
> > > > >
> > > > > Do you have any other suggestions?
> > > > No.
> > > Hmm.. Sorry, I didn't describe my question well.
> > > I mean do you have any suggestions about the API
> > > design for packed ring in uapi header? Currently
> > > I introduced below two new helpers:
> > >
> > > static inline void vring_packed_init(struct vring_packed *vr, unsigned int num,
> > > void *p, unsigned long align);
> > > static inline unsigned vring_packed_size(unsigned int num, unsigned long align);
> > >
> > > When new rings are introduced in the future, above
> > > helpers can't be reused. Maybe we should make the
> > > helpers be able to determine the ring type?
> >
> > Let's wait for Michael's comment here. Generally, I fail to understand why
> > vring_init() become a part of uapi. Git grep shows the only use cases are
> > virtio_test/vringh_test.
> >
> > Thanks
>
> For init - I think it's a mistake that stems from lguest which sometimes
> made it less than obvious which code is where. I don't see a reason to
> add to it.
Got it! I'll move vring_packed_init() out of uapi. Many thanks! :)
Best regards,
Tiwei Bie
>
> --
> MST
^ permalink raw reply
* [PATCH net-next 2/2] mlxsw: spectrum: Add support for auto-negotiation disable mode
From: Ido Schimmel @ 2018-03-21 7:34 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, talb, dsahern, mlxsw, Ido Schimmel
In-Reply-To: <20180321073406.23131-1-idosch@mellanox.com>
From: Tal Bar <talb@mellanox.com>
In 'auto-neg off' the device have sent AN (auto-negotiation) frames
with the forced speed. Thus, fix it using an_disable_admin field in
Port type and speed (PTYS) register. This field indicates if speed
negotiation frames would be send by the port or not.
Add the field and enable/disable it for 'auto-neg on/off', make the
port to start/stop sending AN (auto-negotiation) frames. Note that for
SwitchX2 the behavior doesn't change (i.e support only AN enabled with
forced speed).
Signed-off-by: Tal Bar <talb@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/reg.h | 11 ++++++++++-
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 8 ++++----
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 8 ++++----
3 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index cb5f77f09f8e..e002398364c8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -2872,6 +2872,14 @@ static inline void mlxsw_reg_pmtu_pack(char *payload, u8 local_port,
MLXSW_REG_DEFINE(ptys, MLXSW_REG_PTYS_ID, MLXSW_REG_PTYS_LEN);
+/* an_disable_admin
+ * Auto negotiation disable administrative configuration
+ * 0 - Device doesn't support AN disable.
+ * 1 - Device supports AN disable.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, ptys, an_disable_admin, 0x00, 30, 1);
+
/* reg_ptys_local_port
* Local port number.
* Access: Index
@@ -3000,12 +3008,13 @@ MLXSW_ITEM32(reg, ptys, ib_proto_oper, 0x28, 0, 16);
MLXSW_ITEM32(reg, ptys, eth_proto_lp_advertise, 0x30, 0, 32);
static inline void mlxsw_reg_ptys_eth_pack(char *payload, u8 local_port,
- u32 proto_admin)
+ u32 proto_admin, bool autoneg)
{
MLXSW_REG_ZERO(ptys, payload);
mlxsw_reg_ptys_local_port_set(payload, local_port);
mlxsw_reg_ptys_proto_mask_set(payload, MLXSW_REG_PTYS_PROTO_MASK_ETH);
mlxsw_reg_ptys_eth_proto_admin_set(payload, proto_admin);
+ mlxsw_reg_ptys_an_disable_admin_set(payload, !autoneg);
}
static inline void mlxsw_reg_ptys_eth_unpack(char *payload,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index da8aef7029c8..3f2add1b218d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -2390,7 +2390,7 @@ static int mlxsw_sp_port_get_link_ksettings(struct net_device *dev,
int err;
autoneg = mlxsw_sp_port->link.autoneg;
- mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0);
+ mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0, false);
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
if (err)
return err;
@@ -2424,7 +2424,7 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
bool autoneg;
int err;
- mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0);
+ mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port, 0, false);
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
if (err)
return err;
@@ -2442,7 +2442,7 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
}
mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port,
- eth_proto_new);
+ eth_proto_new, autoneg);
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
if (err)
return err;
@@ -2653,7 +2653,7 @@ mlxsw_sp_port_speed_by_width_set(struct mlxsw_sp_port *mlxsw_sp_port, u8 width)
eth_proto_admin = mlxsw_sp_to_ptys_upper_speed(upper_speed);
mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sp_port->local_port,
- eth_proto_admin);
+ eth_proto_admin, mlxsw_sp_port->link.autoneg);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptys), ptys_pl);
}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
index f3c29bbf07e2..c87b0934a405 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
@@ -789,7 +789,7 @@ mlxsw_sx_port_get_link_ksettings(struct net_device *dev,
u32 supported, advertising, lp_advertising;
int err;
- mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0);
+ mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0, false);
err = mlxsw_reg_query(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
if (err) {
netdev_err(dev, "Failed to get proto");
@@ -879,7 +879,7 @@ mlxsw_sx_port_set_link_ksettings(struct net_device *dev,
mlxsw_sx_to_ptys_advert_link(advertising) :
mlxsw_sx_to_ptys_speed(speed);
- mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0);
+ mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port, 0, false);
err = mlxsw_reg_query(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
if (err) {
netdev_err(dev, "Failed to get proto");
@@ -897,7 +897,7 @@ mlxsw_sx_port_set_link_ksettings(struct net_device *dev,
return 0;
mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port,
- eth_proto_new);
+ eth_proto_new, true);
err = mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
if (err) {
netdev_err(dev, "Failed to set proto admin");
@@ -1029,7 +1029,7 @@ mlxsw_sx_port_speed_by_width_set(struct mlxsw_sx_port *mlxsw_sx_port, u8 width)
eth_proto_admin = mlxsw_sx_to_ptys_upper_speed(upper_speed);
mlxsw_reg_ptys_eth_pack(ptys_pl, mlxsw_sx_port->local_port,
- eth_proto_admin);
+ eth_proto_admin, true);
return mlxsw_reg_write(mlxsw_sx->core, MLXSW_REG(ptys), ptys_pl);
}
--
2.14.3
^ permalink raw reply related
* [PATCH net-next 1/2] mlxsw: spectrum: Update the supported firmware to version 13.1620.192
From: Ido Schimmel @ 2018-03-21 7:34 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, talb, dsahern, mlxsw, Ido Schimmel
In-Reply-To: <20180321073406.23131-1-idosch@mellanox.com>
From: Tal Bar <talb@mellanox.com>
This new firmware contains:
- Support for auto-neg disable mode
Signed-off-by: Tal Bar <talb@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index a120602bca26..da8aef7029c8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -75,8 +75,8 @@
#include "../mlxfw/mlxfw.h"
#define MLXSW_FWREV_MAJOR 13
-#define MLXSW_FWREV_MINOR 1530
-#define MLXSW_FWREV_SUBMINOR 152
+#define MLXSW_FWREV_MINOR 1620
+#define MLXSW_FWREV_SUBMINOR 192
#define MLXSW_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
#define MLXSW_SP_FW_FILENAME \
--
2.14.3
^ permalink raw reply related
* [PATCH net-next 0/2] mlxsw: Update supported firmware version
From: Ido Schimmel @ 2018-03-21 7:34 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, talb, dsahern, mlxsw, Ido Schimmel
Hi,
The first patch bumps the firmware version supported by the driver. The
second patch enables a feature introduced in the new version,
auto-negotiation disable.
Tal Bar (2):
mlxsw: spectrum: Update the supported firmware to version 13.1620.192
mlxsw: spectrum: Add support for auto-negotiation disable mode
drivers/net/ethernet/mellanox/mlxsw/reg.h | 11 ++++++++++-
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 12 ++++++------
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 8 ++++----
3 files changed, 20 insertions(+), 11 deletions(-)
--
2.14.3
^ permalink raw reply
* Re: [PATCH RFC 2/2] virtio_ring: support packed ring
From: Tiwei Bie @ 2018-03-21 7:30 UTC (permalink / raw)
To: Jason Wang; +Cc: mst, netdev, linux-kernel, virtualization, wexu
In-Reply-To: <094ca28b-d8af-bf7a-ea7e-0d0bf7518bda@redhat.com>
On Fri, Mar 16, 2018 at 07:36:47PM +0800, Jason Wang wrote:
> On 2018年03月16日 18:04, Tiwei Bie wrote:
> > On Fri, Mar 16, 2018 at 04:34:28PM +0800, Jason Wang wrote:
> > > On 2018年03月16日 15:40, Tiwei Bie wrote:
> > > > On Fri, Mar 16, 2018 at 02:44:12PM +0800, Jason Wang wrote:
> > > > > On 2018年03月16日 14:10, Tiwei Bie wrote:
> > > > > > On Fri, Mar 16, 2018 at 12:03:25PM +0800, Jason Wang wrote:
> > > > > > > On 2018年02月23日 19:18, Tiwei Bie wrote:
> > > > > > > > Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> > > > > > > > ---
> > > > > > > > drivers/virtio/virtio_ring.c | 699 +++++++++++++++++++++++++++++++++++++------
> > > > > > > > include/linux/virtio_ring.h | 8 +-
> > > > > > > > 2 files changed, 618 insertions(+), 89 deletions(-)
[...]
> > > @@ -1096,17 +1599,21 @@ struct virtqueue *vring_create_virtqueue(
> > > > > > > > if (!queue) {
> > > > > > > > /* Try to get a single page. You are my only hope! */
> > > > > > > > - queue = vring_alloc_queue(vdev, vring_size(num, vring_align),
> > > > > > > > + queue = vring_alloc_queue(vdev, __vring_size(num, vring_align,
> > > > > > > > + packed),
> > > > > > > > &dma_addr, GFP_KERNEL|__GFP_ZERO);
> > > > > > > > }
> > > > > > > > if (!queue)
> > > > > > > > return NULL;
> > > > > > > > - queue_size_in_bytes = vring_size(num, vring_align);
> > > > > > > > - vring_init(&vring, num, queue, vring_align);
> > > > > > > > + queue_size_in_bytes = __vring_size(num, vring_align, packed);
> > > > > > > > + if (packed)
> > > > > > > > + vring_packed_init(&vring.vring_packed, num, queue, vring_align);
> > > > > > > > + else
> > > > > > > > + vring_init(&vring.vring_split, num, queue, vring_align);
> > > > > > > Let's rename vring_init to vring_init_split() like other helpers?
> > > > > > The vring_init() is a public API in include/uapi/linux/virtio_ring.h.
> > > > > > I don't think we can rename it.
> > > > > I see, then this need more thoughts to unify the API.
> > > > My thought is to keep the old API as is, and introduce
> > > > new types and helpers for packed ring.
> > > I admit it's not a fault of this patch. But we'd better think of this in the
> > > future, consider we may have new kinds of ring.
> > >
> > > > More details can be found in this patch:
> > > > https://lkml.org/lkml/2018/2/23/243
> > > > (PS. The type which has bit fields is just for reference,
> > > > and will be changed in next version.)
> > > >
> > > > Do you have any other suggestions?
> > > No.
> > Hmm.. Sorry, I didn't describe my question well.
> > I mean do you have any suggestions about the API
> > design for packed ring in uapi header? Currently
> > I introduced below two new helpers:
> >
> > static inline void vring_packed_init(struct vring_packed *vr, unsigned int num,
> > void *p, unsigned long align);
> > static inline unsigned vring_packed_size(unsigned int num, unsigned long align);
> >
> > When new rings are introduced in the future, above
> > helpers can't be reused. Maybe we should make the
> > helpers be able to determine the ring type?
>
> Let's wait for Michael's comment here. Generally, I fail to understand why
> vring_init() become a part of uapi. Git grep shows the only use cases are
> virtio_test/vringh_test.
Thank you very much for the review on this patch!
I'll send out a new version ASAP to address these
comments. :)
Best regards,
Tiwei Bie
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* [PATCH net-next v4 2/2] net: bpf: add a test for skb_segment in test_bpf module
From: Yonghong Song @ 2018-03-21 6:47 UTC (permalink / raw)
To: edumazet, ast, daniel, diptanu, netdev; +Cc: kernel-team
In-Reply-To: <20180321064722.1411857-1-yhs@fb.com>
Without the previous commit,
"modprobe test_bpf" will have the following errors:
...
[ 98.149165] ------------[ cut here ]------------
[ 98.159362] kernel BUG at net/core/skbuff.c:3667!
[ 98.169756] invalid opcode: 0000 [#1] SMP PTI
[ 98.179370] Modules linked in:
[ 98.179371] test_bpf(+)
...
which triggers the bug the previous commit intends to fix.
The skbs are constructed to mimic what mlx5 may generate.
The packet size/header may not mimic real cases in production. But
the processing flow is similar.
Signed-off-by: Yonghong Song <yhs@fb.com>
---
lib/test_bpf.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 89 insertions(+), 2 deletions(-)
diff --git a/lib/test_bpf.c b/lib/test_bpf.c
index 2efb213..086a231 100644
--- a/lib/test_bpf.c
+++ b/lib/test_bpf.c
@@ -6574,6 +6574,91 @@ static bool exclude_test(int test_id)
return test_id < test_range[0] || test_id > test_range[1];
}
+static __init struct sk_buff *build_test_skb(void)
+{
+ u32 headroom = NET_SKB_PAD + NET_IP_ALIGN + ETH_HLEN;
+ struct sk_buff *skb[2];
+ struct page *page[2];
+ int i, data_size = 8;
+
+ for (i = 0; i < 2; i++) {
+ page[i] = alloc_page(GFP_KERNEL);
+ if (!page[i]) {
+ if (i == 0)
+ goto err_page0;
+ else
+ goto err_page1;
+ }
+
+ /* this will set skb[i]->head_frag */
+ skb[i] = dev_alloc_skb(headroom + data_size);
+ if (!skb[i]) {
+ if (i == 0)
+ goto err_skb0;
+ else
+ goto err_skb1;
+ }
+
+ skb_reserve(skb[i], headroom);
+ skb_put(skb[i], data_size);
+ skb[i]->protocol = htons(ETH_P_IP);
+ skb_reset_network_header(skb[i]);
+ skb_set_mac_header(skb[i], -ETH_HLEN);
+
+ skb_add_rx_frag(skb[i], 0, page[i], 0, 64, 64);
+ // skb_headlen(skb[i]): 8, skb[i]->head_frag = 1
+ }
+
+ /* setup shinfo */
+ skb_shinfo(skb[0])->gso_size = 1448;
+ skb_shinfo(skb[0])->gso_type = SKB_GSO_TCPV4;
+ skb_shinfo(skb[0])->gso_type |= SKB_GSO_DODGY;
+ skb_shinfo(skb[0])->gso_segs = 0;
+ skb_shinfo(skb[0])->frag_list = skb[1];
+
+ /* adjust skb[0]'s len */
+ skb[0]->len += skb[1]->len;
+ skb[0]->data_len += skb[1]->data_len;
+ skb[0]->truesize += skb[1]->truesize;
+
+ return skb[0];
+
+err_skb1:
+ __free_page(page[1]);
+err_page1:
+ kfree_skb(skb[0]);
+err_skb0:
+ __free_page(page[0]);
+err_page0:
+ return NULL;
+}
+
+static __init int test_skb_segment(void)
+{
+ netdev_features_t features;
+ struct sk_buff *skb;
+ int ret = -1;
+
+ features = NETIF_F_SG | NETIF_F_GSO_PARTIAL | NETIF_F_IP_CSUM |
+ NETIF_F_IPV6_CSUM;
+ features |= NETIF_F_RXCSUM;
+ skb = build_test_skb();
+ if (!skb) {
+ pr_info("%s: failed to build_test_skb", __func__);
+ goto done;
+ }
+
+ if (skb_segment(skb, features)) {
+ ret = 0;
+ pr_info("%s: success in skb_segment!", __func__);
+ } else {
+ pr_info("%s: failed in skb_segment!", __func__);
+ }
+ kfree_skb(skb);
+done:
+ return ret;
+}
+
static __init int test_bpf(void)
{
int i, err_cnt = 0, pass_cnt = 0;
@@ -6632,9 +6717,11 @@ static int __init test_bpf_init(void)
return ret;
ret = test_bpf();
-
destroy_bpf_tests();
- return ret;
+ if (ret)
+ return ret;
+
+ return test_skb_segment();
}
static void __exit test_bpf_exit(void)
--
2.9.5
^ permalink raw reply related
* [PATCH net-next v4 1/2] net: permit skb_segment on head_frag frag_list skb
From: Yonghong Song @ 2018-03-21 6:47 UTC (permalink / raw)
To: edumazet, ast, daniel, diptanu, netdev; +Cc: kernel-team
In-Reply-To: <20180321064722.1411857-1-yhs@fb.com>
One of our in-house projects, bpf-based NAT, hits a kernel BUG_ON at
function skb_segment(), line 3667. The bpf program attaches to
clsact ingress, calls bpf_skb_change_proto to change protocol
from ipv4 to ipv6 or from ipv6 to ipv4, and then calls bpf_redirect
to send the changed packet out.
3472 struct sk_buff *skb_segment(struct sk_buff *head_skb,
3473 netdev_features_t features)
3474 {
3475 struct sk_buff *segs = NULL;
3476 struct sk_buff *tail = NULL;
...
3665 while (pos < offset + len) {
3666 if (i >= nfrags) {
3667 BUG_ON(skb_headlen(list_skb));
3668
3669 i = 0;
3670 nfrags = skb_shinfo(list_skb)->nr_frags;
3671 frag = skb_shinfo(list_skb)->frags;
3672 frag_skb = list_skb;
...
call stack:
...
#1 [ffff883ffef03558] __crash_kexec at ffffffff8110c525
#2 [ffff883ffef03620] crash_kexec at ffffffff8110d5cc
#3 [ffff883ffef03640] oops_end at ffffffff8101d7e7
#4 [ffff883ffef03668] die at ffffffff8101deb2
#5 [ffff883ffef03698] do_trap at ffffffff8101a700
#6 [ffff883ffef036e8] do_error_trap at ffffffff8101abfe
#7 [ffff883ffef037a0] do_invalid_op at ffffffff8101acd0
#8 [ffff883ffef037b0] invalid_op at ffffffff81a00bab
[exception RIP: skb_segment+3044]
RIP: ffffffff817e4dd4 RSP: ffff883ffef03860 RFLAGS: 00010216
RAX: 0000000000002bf6 RBX: ffff883feb7aaa00 RCX: 0000000000000011
RDX: ffff883fb87910c0 RSI: 0000000000000011 RDI: ffff883feb7ab500
RBP: ffff883ffef03928 R8: 0000000000002ce2 R9: 00000000000027da
R10: 000001ea00000000 R11: 0000000000002d82 R12: ffff883f90a1ee80
R13: ffff883fb8791120 R14: ffff883feb7abc00 R15: 0000000000002ce2
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#9 [ffff883ffef03930] tcp_gso_segment at ffffffff818713e7
--- <IRQ stack> ---
...
The triggering input skb has the following properties:
list_skb = skb->frag_list;
skb->nfrags != NULL && skb_headlen(list_skb) != 0
and skb_segment() is not able to handle a frag_list skb
if its headlen (list_skb->len - list_skb->data_len) is not 0.
This patch addressed the issue by handling skb_headlen(list_skb) != 0
case properly if list_skb->head_frag is true, which is expected in
most cases. The head frag is processed before list_skb->frags
are processed.
Reported-by: Diptanu Gon Choudhury <diptanu@fb.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
---
net/core/skbuff.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 715c134..09f4c24 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3475,7 +3475,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
struct sk_buff *segs = NULL;
struct sk_buff *tail = NULL;
struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list;
- skb_frag_t *frag = skb_shinfo(head_skb)->frags;
+ skb_frag_t *frag = skb_shinfo(head_skb)->frags, head_frag;
unsigned int mss = skb_shinfo(head_skb)->gso_size;
unsigned int doffset = head_skb->data - skb_mac_header(head_skb);
struct sk_buff *frag_skb = head_skb;
@@ -3664,19 +3664,30 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
while (pos < offset + len) {
if (i >= nfrags) {
- BUG_ON(skb_headlen(list_skb));
-
i = 0;
nfrags = skb_shinfo(list_skb)->nr_frags;
frag = skb_shinfo(list_skb)->frags;
- frag_skb = list_skb;
-
- BUG_ON(!nfrags);
+ if (skb_headlen(list_skb)) {
+ struct page *page;
+
+ BUG_ON(!list_skb->head_frag);
+
+ page = virt_to_head_page(list_skb->head);
+ head_frag.page.p = page;
+ head_frag.page_offset = list_skb->data -
+ (unsigned char *)page_address(page);
+ head_frag.size = skb_headlen(list_skb);
+ /* to make room for head_frag. */
+ i--; frag--;
+ }
+ if (nfrags) {
+ frag_skb = list_skb;
- if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
- skb_zerocopy_clone(nskb, frag_skb,
- GFP_ATOMIC))
- goto err;
+ if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
+ skb_zerocopy_clone(nskb, frag_skb,
+ GFP_ATOMIC))
+ goto err;
+ }
list_skb = list_skb->next;
}
@@ -3689,7 +3700,10 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
goto err;
}
- *nskb_frag = *frag;
+ /* head_frag could be defined in previous outer do/while
+ * loop iterations.
+ */
+ *nskb_frag = (i < 0) ? head_frag : *frag;
__skb_frag_ref(nskb_frag);
size = skb_frag_size(nskb_frag);
--
2.9.5
^ permalink raw reply related
* [PATCH net-next v4 0/2] net: permit skb_segment on head_frag frag_list skb
From: Yonghong Song @ 2018-03-21 6:47 UTC (permalink / raw)
To: edumazet, ast, daniel, diptanu, netdev; +Cc: kernel-team
One of our in-house projects, bpf-based NAT, hits a kernel BUG_ON at
function skb_segment(), line 3667. The bpf program attaches to
clsact ingress, calls bpf_skb_change_proto to change protocol
from ipv4 to ipv6 or from ipv6 to ipv4, and then calls bpf_redirect
to send the changed packet out.
...
3665 while (pos < offset + len) {
3666 if (i >= nfrags) {
3667 BUG_ON(skb_headlen(list_skb));
...
The triggering input skb has the following properties:
list_skb = skb->frag_list;
skb->nfrags != NULL && skb_headlen(list_skb) != 0
and skb_segment() is not able to handle a frag_list skb
if its headlen (list_skb->len - list_skb->data_len) is not 0.
Patch #1 provides a simple solution to avoid BUG_ON. If
list_skb->head_frag is true, its page-backed frag will
be processed before the list_skb->frags.
Patch #2 provides a test case in test_bpf module which
constructs a skb and calls skb_segment() directly. The test
case is able to trigger the BUG_ON without Patch #1.
The patch has been tested in the following setup:
ipv6_host <-> nat_server <-> ipv4_host
where nat_server has a bpf program doing ipv4<->ipv6
translation and forwarding through clsact hook
bpf_skb_change_proto.
Changelog:
v3 -> v4:
. Remove dynamic memory allocation and use rewinding
for both index and frag to remove one branch in fast path,
from Alexander.
. Fix a bunch of issues in test_bpf skb_segment() test,
including proper way to allocate skb, proper function
argument for skb_add_rx_frag and not freeint skb, etc.,
from Eric.
v2 -> v3:
. Use starting frag index -1 (instead of 0) to
special process head_frag before other frags in the skb,
from Alexander Duyck.
v1 -> v2:
. Removed never-hit BUG_ON, spotted by Linyu Yuan.
Yonghong Song (2):
net: permit skb_segment on head_frag frag_list skb
net: bpf: add a test for skb_segment in test_bpf module
lib/test_bpf.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
net/core/skbuff.c | 36 +++++++++++++++-------
2 files changed, 114 insertions(+), 13 deletions(-)
--
2.9.5
^ permalink raw reply
* Re: [RFC PATCH 0/3] kernel: add support for 256-bit IO access
From: Ingo Molnar @ 2018-03-21 6:32 UTC (permalink / raw)
To: Linus Torvalds
Cc: Thomas Gleixner, David Laight, Rahul Lakkireddy, x86@kernel.org,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
mingo@redhat.com, hpa@zytor.com, davem@davemloft.net,
akpm@linux-foundation.org, ganeshgr@chelsio.com,
nirranjan@chelsio.com, indranil@chelsio.com, Andy Lutomirski,
Peter Zijlstra, Fenghua Yu, Eric Biggers
In-Reply-To: <CA+55aFybTvLz47mw=AG21jCJv_hE2vaVyiJP_F-4vAD-3Gnc7Q@mail.gmail.com>
* Linus Torvalds <torvalds@linux-foundation.org> wrote:
> And even if you ignore that "maintenance problems down the line" issue
> ("we can fix them when they happen") I don't want to see games like
> this, because I'm pretty sure it breaks the optimized xsave by tagging
> the state as being dirty.
That's true - and it would penalize the context switch cost of the affected task
for the rest of its lifetime, as I don't think there's much that clears XINUSE
other than a FINIT, which is rarely done by user-space.
> So no. Don't use vector stuff in the kernel. It's not worth the pain.
I agree, but:
> The *only* valid use is pretty much crypto, and even there it has had issues.
> Benchmarks use big arrays and/or dense working sets etc to "prove" how good the
> vector version is, and then you end up in situations where it's used once per
> fairly small packet for an interrupt, and it's actually much worse than doing it
> by hand.
That's mainly because the XSAVE/XRESTOR done by kernel_fpu_begin()/end() is so
expensive, so this argument is somewhat circular.
IFF it was safe to just use the vector unit then vector unit based crypto would be
very fast for small buffer as well, and would be even faster for larger buffer
sizes as well. Saving and restoring up to ~1.5K of context is not cheap.
Thanks,
Ingo
^ permalink raw reply
* Re: [PATCH net-next 5/6] tls: RX path for ktls
From: Boris Pismenny @ 2018-03-21 5:20 UTC (permalink / raw)
To: Dave Watson, David S. Miller, Tom Herbert, Alexei Starovoitov,
herbert, linux-crypto, netdev
Cc: Atul Gupta, Vakul Garg, Hannes Frederic Sowa, Steffen Klassert,
John Fastabend, Daniel Borkmann
In-Reply-To: <20180320175434.GA23938@davejwatson-mba.local>
On 3/20/2018 7:54 PM, Dave Watson wrote:
> Add rx path for tls software implementation.
>
> recvmsg, splice_read, and poll implemented.
>
> An additional sockopt TLS_RX is added, with the same interface as
> TLS_TX. Either TLX_RX or TLX_TX may be provided separately, or
> together (with two different setsockopt calls with appropriate keys).
>
> Control messages are passed via CMSG in a similar way to transmit.
> If no cmsg buffer is passed, then only application data records
> will be passed to userspace, and EIO is returned for other types of
> alerts.
>
> EBADMSG is passed for decryption errors, and EMSGSIZE is passed for
> framing errors (either framing too big *or* too small with crypto
> overhead). EINVAL is returned for TLS versions that do not match the
> original setsockopt call. All are unrecoverable.
>
> strparser is used to parse TLS framing. Decryption is done directly
> in to userspace buffers if they are large enough to support it, otherwise
> sk_cow_data is called (similar to ipsec), and buffers are decrypted in
> place and copied. splice_read always decrypts in place, since no
> buffers are provided to decrypt in to.
>
> sk_poll is overridden, and only returns POLLIN if a full TLS message is
> received. Otherwise we wait for strparser to finish reading a full frame.
> Actual decryption is only done during recvmsg or splice_read calls.
>
> Signed-off-by: Dave Watson <davejwatson@fb.com>
> ---
...
> +
> +static int tls_read_size(struct strparser *strp, struct sk_buff *skb)
> +{
> + struct tls_context *tls_ctx = tls_get_ctx(strp->sk);
> + struct tls_sw_context *ctx = tls_sw_ctx(tls_ctx);
> + char header[tls_ctx->rx.prepend_size];
> + struct strp_msg *rxm = strp_msg(skb);
> + size_t cipher_overhead;
> + size_t data_len = 0;
> + int ret;
> +
> + /* Verify that we have a full TLS header, or wait for more data */
> + if (rxm->offset + tls_ctx->rx.prepend_size > skb->len)
> + return 0;
> +
> + /* Linearize header to local buffer */
> + ret = skb_copy_bits(skb, rxm->offset, header, tls_ctx->rx.prepend_size);
> +
> + if (ret < 0)
> + goto read_failure;
> +
> + ctx->control = header[0];
> +
> + data_len = ((header[4] & 0xFF) | (header[3] << 8));
> +
> + cipher_overhead = tls_ctx->rx.tag_size + tls_ctx->rx.iv_size;
> +
> + if (data_len > TLS_MAX_PAYLOAD_SIZE + cipher_overhead) {
> + ret = -EMSGSIZE;
> + goto read_failure;
> + }
> + if (data_len < cipher_overhead) {
> + ret = -EMSGSIZE;
I think this should be considered EBADMSG, because this error is cipher
dependent. At least, that's what happens within OpenSSL. Also, EMSGSIZE
is usually used only for too long messages.
> + goto read_failure;
> + }
> +
> + if (header[1] != TLS_VERSION_MINOR(tls_ctx->crypto_recv.version) ||
> + header[2] != TLS_VERSION_MAJOR(tls_ctx->crypto_recv.version)) {
> + ret = -EINVAL;
> + goto read_failure;
> + }
> +
> + return data_len + TLS_HEADER_SIZE;
> +
> +read_failure:
> + tls_err_abort(strp->sk, ret);
> +
> + return ret;
> +}
> +
...
^ permalink raw reply
* Re: [PATCH net-next v3 2/2] net: bpf: add a test for skb_segment in test_bpf module
From: Yonghong Song @ 2018-03-21 5:15 UTC (permalink / raw)
To: Eric Dumazet, edumazet, ast, daniel, diptanu, netdev,
alexander.duyck
Cc: kernel-team
In-Reply-To: <890b597a-85b6-a3fc-3419-8cace6d0f2b7@gmail.com>
On 3/20/18 5:44 PM, Eric Dumazet wrote:
>
>
> On 03/20/2018 04:21 PM, Yonghong Song wrote:
>> Without the previous commit,
>> "modprobe test_bpf" will have the following errors:
>> ...
>> [ 98.149165] ------------[ cut here ]------------
>> [ 98.159362] kernel BUG at net/core/skbuff.c:3667!
>> [ 98.169756] invalid opcode: 0000 [#1] SMP PTI
>> [ 98.179370] Modules linked in:
>> [ 98.179371] test_bpf(+)
>> ...
>> which triggers the bug the previous commit intends to fix.
>>
>> The skbs are constructed to mimic what mlx5 may generate.
>> The packet size/header may not mimic real cases in production. But
>> the processing flow is similar.
>>
>> Signed-off-by: Yonghong Song <yhs@fb.com>
>> ---
>> lib/test_bpf.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 70 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/test_bpf.c b/lib/test_bpf.c
>> index 2efb213..045d7d3 100644
>> --- a/lib/test_bpf.c
>> +++ b/lib/test_bpf.c
>> @@ -6574,6 +6574,72 @@ static bool exclude_test(int test_id)
>> return test_id < test_range[0] || test_id > test_range[1];
>> }
>>
>> +static struct sk_buff *build_test_skb(void *page)
>> +{
>> + u32 headroom = NET_SKB_PAD + NET_IP_ALIGN + ETH_HLEN;
>> + struct sk_buff *skb[2];
>> + int i, data_size = 8;
>> +
>> + for (i = 0; i < 2; i++) {
>> + /* this will set skb[i]->head_frag */
>> + skb[i] = build_skb(page, headroom);
>> + if (!skb[i])
>> + return NULL;
>
> You are using the same virtual address (page) for both skb ?
>
> So we have 2 skbs having skb->head pointing to the same location ?
Thanks, Eric. This is purely due to my 'laziness' to make it work as I
know that skb_segment does not really enforce this. I will address
all of your comments in the next revision.
>
> This is illegal.
>
> Please use instead : skb = dev_alloc_skb(headroom + data_size)
>
>> +
>> + skb_reserve(skb[i], headroom);
>> + skb_put(skb[i], data_size);
>> + skb[i]->protocol = htons(ETH_P_IP);
>> + skb_reset_network_header(skb[i]);
>> + skb_set_mac_header(skb[i], -ETH_HLEN);
>> +
>> + skb_add_rx_frag(skb[i],
>
> skb_shinfo(skb[i])->nr_frags,
>
> 0 ?
>
>> + page, 0, 64, 64);
>
> get_page(page) ?
>
>> + // skb: skb_headlen(skb[i]): 8, skb[i]->head_frag = 1
>> + }
>> +
>> + /* setup shinfo */
>> + skb_shinfo(skb[0])->gso_size = 1448;
>> + skb_shinfo(skb[0])->gso_type = SKB_GSO_TCPV4;
>> + skb_shinfo(skb[0])->gso_type |= SKB_GSO_DODGY;
>> + skb_shinfo(skb[0])->gso_segs = 0;
>> + skb_shinfo(skb[0])->frag_list = skb[1];
>> +
>> + /* adjust skb[0]'s len */
>> + skb[0]->len += skb[1]->len;
>> + skb[0]->data_len += skb[1]->data_len;
>> + skb[0]->truesize += skb[1]->truesize;
>> +
>> + return skb[0];
>> +}
>> +
>> +static __init int test_skb_segment(void)
>> +{
>> + netdev_features_t features;
>> + struct sk_buff *skb;
>> + void *page;
>> + int ret = -1;
>> +
>> + page = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
>> + if (!page) {
>> + pr_info("%s: failed to get_free_page!", __func__);
>> + return ret;
>> + }
>> +
>> + features = NETIF_F_SG | NETIF_F_GSO_PARTIAL | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
>> + features |= NETIF_F_RXCSUM;
>> + skb = build_test_skb(page);
>> + if (!skb) {
>> + pr_info("%s: failed to build_test_skb", __func__);
>> + } else if (skb_segment(skb, features)) {
>> + ret = 0;
>> + pr_info("%s: success in skb_segment!", __func__);
>> + } else {
>> + pr_info("%s: failed in skb_segment!", __func__);
>> + }
>> + free_page((unsigned long)page);
>
>
> Where are the skbs freed ?
>
>
>> + return ret;
>> +}
>> +
>> static __init int test_bpf(void)
>> {
>> int i, err_cnt = 0, pass_cnt = 0;
>> @@ -6632,8 +6698,11 @@ static int __init test_bpf_init(void)
>> return ret;
>>
>> ret = test_bpf();
>> -
>> destroy_bpf_tests();
>> + if (ret)
>> + return ret;
>> +
>> + ret = test_skb_segment();
>> return ret;
>> }
>>
>>
^ permalink raw reply
* Re: [PATCH net-next v3 1/2] net: permit skb_segment on head_frag frag_list skb
From: Yonghong Song @ 2018-03-21 5:02 UTC (permalink / raw)
To: Alexander Duyck
Cc: Eric Dumazet, ast, Daniel Borkmann, diptanu, Netdev, Kernel Team
In-Reply-To: <CAKgT0Ud3=qh-7mAHGfKQfhF+Q3scmKfhVhZgtnMfQ5Sy6-Msag@mail.gmail.com>
On 3/20/18 4:50 PM, Alexander Duyck wrote:
> On Tue, Mar 20, 2018 at 4:21 PM, Yonghong Song <yhs@fb.com> wrote:
>> One of our in-house projects, bpf-based NAT, hits a kernel BUG_ON at
>> function skb_segment(), line 3667. The bpf program attaches to
>> clsact ingress, calls bpf_skb_change_proto to change protocol
>> from ipv4 to ipv6 or from ipv6 to ipv4, and then calls bpf_redirect
>> to send the changed packet out.
>>
>> 3472 struct sk_buff *skb_segment(struct sk_buff *head_skb,
>> 3473 netdev_features_t features)
>> 3474 {
>> 3475 struct sk_buff *segs = NULL;
>> 3476 struct sk_buff *tail = NULL;
>> ...
>> 3665 while (pos < offset + len) {
>> 3666 if (i >= nfrags) {
>> 3667 BUG_ON(skb_headlen(list_skb));
>> 3668
>> 3669 i = 0;
>> 3670 nfrags = skb_shinfo(list_skb)->nr_frags;
>> 3671 frag = skb_shinfo(list_skb)->frags;
>> 3672 frag_skb = list_skb;
>> ...
>>
>> call stack:
>> ...
>> #1 [ffff883ffef03558] __crash_kexec at ffffffff8110c525
>> #2 [ffff883ffef03620] crash_kexec at ffffffff8110d5cc
>> #3 [ffff883ffef03640] oops_end at ffffffff8101d7e7
>> #4 [ffff883ffef03668] die at ffffffff8101deb2
>> #5 [ffff883ffef03698] do_trap at ffffffff8101a700
>> #6 [ffff883ffef036e8] do_error_trap at ffffffff8101abfe
>> #7 [ffff883ffef037a0] do_invalid_op at ffffffff8101acd0
>> #8 [ffff883ffef037b0] invalid_op at ffffffff81a00bab
>> [exception RIP: skb_segment+3044]
>> RIP: ffffffff817e4dd4 RSP: ffff883ffef03860 RFLAGS: 00010216
>> RAX: 0000000000002bf6 RBX: ffff883feb7aaa00 RCX: 0000000000000011
>> RDX: ffff883fb87910c0 RSI: 0000000000000011 RDI: ffff883feb7ab500
>> RBP: ffff883ffef03928 R8: 0000000000002ce2 R9: 00000000000027da
>> R10: 000001ea00000000 R11: 0000000000002d82 R12: ffff883f90a1ee80
>> R13: ffff883fb8791120 R14: ffff883feb7abc00 R15: 0000000000002ce2
>> ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
>> #9 [ffff883ffef03930] tcp_gso_segment at ffffffff818713e7
>> --- <IRQ stack> ---
>> ...
>>
>> The triggering input skb has the following properties:
>> list_skb = skb->frag_list;
>> skb->nfrags != NULL && skb_headlen(list_skb) != 0
>> and skb_segment() is not able to handle a frag_list skb
>> if its headlen (list_skb->len - list_skb->data_len) is not 0.
>>
>> This patch addressed the issue by handling skb_headlen(list_skb) != 0
>> case properly if list_skb->head_frag is true, which is expected in
>> most cases. The head frag is processed before list_skb->frags
>> are processed.
>>
>> Reported-by: Diptanu Gon Choudhury <diptanu@fb.com>
>> Signed-off-by: Yonghong Song <yhs@fb.com>
>> ---
>> net/core/skbuff.c | 51 +++++++++++++++++++++++++++++++++++++--------------
>> 1 file changed, 37 insertions(+), 14 deletions(-)
>>
>> diff --git a/net/core/skbuff.c b/net/core/skbuff.c
>> index 715c134..59bbc06 100644
>> --- a/net/core/skbuff.c
>> +++ b/net/core/skbuff.c
>> @@ -3475,7 +3475,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
>> struct sk_buff *segs = NULL;
>> struct sk_buff *tail = NULL;
>> struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list;
>> - skb_frag_t *frag = skb_shinfo(head_skb)->frags;
>> + skb_frag_t *frag = skb_shinfo(head_skb)->frags, *head_frag = NULL;
>
> I think you misunderstood me. I wasn't saying you allocate head_frag.
> I was saying you could move the declaration down.
Sorry for my misunderstanding. I did understand your intention of moving
the declaration down in order to save stack space. I thought that we
cannot really move declaration down (although it works in C, but
semantically it is not quite right, more later), so I moved on to
use runtime allocation. But indeed skb_frag_t is not big (16 bytes), it
could live on the stack.
>
>> unsigned int mss = skb_shinfo(head_skb)->gso_size;
>> unsigned int doffset = head_skb->data - skb_mac_header(head_skb);
>> struct sk_buff *frag_skb = head_skb;
>> @@ -3664,19 +3664,39 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
>>
>> while (pos < offset + len) {
>
> So right here in the loop you could add a "skb_frag_t head_frag;" just
> so we declare it here and save ourselves the stack space.
I actually tried to move "skb_frag_t head_frag". The stack size remains
the same, 0xc0. This is related to how C compiler allocates stack space.
The declaration place won't decide the stack size as long as the
declaration dictates the usage. The stack size is really determined by
liveness analysis.
Further, we have code like:
do {
....
while (pos < offset + len) {
if (i >= nfrags) {
...
head_frag = ...
}
... = head_frag; // head_frag access guaranteed after
// above definition, but it may not
// be in the same outer do-while loop.
}
...
} while (((offset += len) < head_skb->len);
So the use of head_frag maybe in different outer loop iterations.
So I feel the definition of head_frag should be outside the
outer do-while loop, which is the main function scope. I will add some
comments here.
>
>> if (i >= nfrags) {
>> - BUG_ON(skb_headlen(list_skb));
>> -
>> i = 0;
>> + if (skb_headlen(list_skb)) {
>> + struct page *page;
>> +
>> + BUG_ON(!list_skb->head_frag);
>> +
>> + page = virt_to_head_page(list_skb->head);
>> + if (!head_frag) {
>> + head_frag = kmalloc(sizeof(skb_frag_t),
>> + GFP_KERNEL);
>> + if (!head_frag)
>> + goto err;
>> + }
>
> Please no memory allocation. I just meant you could allocate it on the
> stack later.
>
>> + head_frag->page.p = page;
>> + head_frag->page_offset = list_skb->data -
>> + (unsigned char *)page_address(page);
>> + head_frag->size = skb_headlen(list_skb);
>> + /* set i = -1 so we will pick head_frag
>> + * instead of skb_shinfo(list_skb)->frags
>> + * when i == -1.
>> + */
>> + i = -1;
>> + }
>
> So it took me a bit to pick up on the fact that line below wasn't
> removed. So we are basically trying to do this all in one pass now. Do
> I have that right?
>
> One thing you could look at doing to save yourself the extra "if"
> later would be to pull frag pointer before you go through skb_headlen
> check above. Then if you are going to use a head_frag you could just
> do a "i--; frag--;" combination just to rewind and make the room for
> the increment to come later. That way you don't have an invalid frag
> pointer floating around. That way you only have to do this once
> instead of having to do a conditional check per fragment.
Right. This indeed make code more cleaner.
>
>> nfrags = skb_shinfo(list_skb)->nr_frags;
>> - frag = skb_shinfo(list_skb)->frags;
>
> This patch might be more readable if you were to just insert the
> skb_headlen() bits down here and left the i=0 through frag = .. in one
> piece.
Right. Will implement as suggested.
>
>> - frag_skb = list_skb;
>> -
>> - BUG_ON(!nfrags);
>> -
>> - if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
>> - skb_zerocopy_clone(nskb, frag_skb,
>> - GFP_ATOMIC))
>> - goto err;
>> + if (nfrags) {
>> + frag = skb_shinfo(list_skb)->frags;
>> + frag_skb = list_skb;
>> +
>> + if (skb_orphan_frags(frag_skb, GFP_ATOMIC) ||
>> + skb_zerocopy_clone(nskb, frag_skb,
>> + GFP_ATOMIC))
>> + goto err;
>> + }
>>
>> list_skb = list_skb->next;
>> }
>> @@ -3689,7 +3709,7 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
>> goto err;
>> }
>>
>> - *nskb_frag = *frag;
>> + *nskb_frag = (i == -1) ? *head_frag : *frag;
>
> So this would be better as "*nskb_frag = (i < 0) ? head_frag : *frag;".
Good suggestion. Will implement as suggested.
>
>> __skb_frag_ref(nskb_frag);
>> size = skb_frag_size(nskb_frag);
>>
>> @@ -3702,7 +3722,8 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
>>
>> if (pos + size <= offset + len) {
>> i++;
>> - frag++;
>> + if (i != 0)
>> + frag++;
>> pos += size;
>> } else {
>> skb_frag_size_sub(nskb_frag, pos + size - (offset + len));
>> @@ -3774,10 +3795,12 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
>> swap(tail->destructor, head_skb->destructor);
>> swap(tail->sk, head_skb->sk);
>> }
>> + kfree(head_frag);
>> return segs;
>>
>> err:
>> kfree_skb_list(segs);
>> + kfree(head_frag);
>> return ERR_PTR(err);
>> }
>> EXPORT_SYMBOL_GPL(skb_segment);
>> --
>> 2.9.5
>>
^ permalink raw reply
* [PATCH net-next] devlink: Remove top_hierarchy arg to devlink_resource_register
From: David Ahern @ 2018-03-21 2:31 UTC (permalink / raw)
To: netdev; +Cc: arkadis, jiri, David Ahern
top_hierarchy arg can be determined by comparing parent_resource_id to
DEVLINK_RESOURCE_ID_PARENT_TOP so it does not need to be a separate
argument.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 9 ++++-----
drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c | 6 +++---
include/net/devlink.h | 1 -
net/core/devlink.c | 4 +++-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 7884e8a2de35..180f49fbebe4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3880,8 +3880,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
kvd_size = MLXSW_CORE_RES_GET(mlxsw_core, KVD_SIZE);
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD,
- true, kvd_size,
- MLXSW_SP_RESOURCE_KVD,
+ kvd_size, MLXSW_SP_RESOURCE_KVD,
DEVLINK_RESOURCE_ID_PARENT_TOP,
&kvd_size_params,
NULL);
@@ -3890,7 +3889,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
linear_size = profile->kvd_linear_size;
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR,
- false, linear_size,
+ linear_size,
MLXSW_SP_RESOURCE_KVD_LINEAR,
MLXSW_SP_RESOURCE_KVD,
&linear_size_params,
@@ -3908,7 +3907,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
profile->kvd_hash_single_parts;
double_size = rounddown(double_size, profile->kvd_hash_granularity);
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_DOUBLE,
- false, double_size,
+ double_size,
MLXSW_SP_RESOURCE_KVD_HASH_DOUBLE,
MLXSW_SP_RESOURCE_KVD,
&hash_double_size_params,
@@ -3918,7 +3917,7 @@ static int mlxsw_sp_resources_register(struct mlxsw_core *mlxsw_core)
single_size = kvd_size - double_size - linear_size;
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_HASH_SINGLE,
- false, single_size,
+ single_size,
MLXSW_SP_RESOURCE_KVD_HASH_SINGLE,
MLXSW_SP_RESOURCE_KVD,
&hash_single_size_params,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c
index 4c9bff2fa055..85503e93b93f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_kvdl.c
@@ -459,7 +459,7 @@ int mlxsw_sp_kvdl_resources_register(struct devlink *devlink)
mlxsw_sp_kvdl_resource_size_params_prepare(devlink);
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_SINGLES,
- false, MLXSW_SP_KVDL_SINGLE_SIZE,
+ MLXSW_SP_KVDL_SINGLE_SIZE,
MLXSW_SP_RESOURCE_KVD_LINEAR_SINGLE,
MLXSW_SP_RESOURCE_KVD_LINEAR,
&mlxsw_sp_kvdl_single_size_params,
@@ -468,7 +468,7 @@ int mlxsw_sp_kvdl_resources_register(struct devlink *devlink)
return err;
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_CHUNKS,
- false, MLXSW_SP_KVDL_CHUNKS_SIZE,
+ MLXSW_SP_KVDL_CHUNKS_SIZE,
MLXSW_SP_RESOURCE_KVD_LINEAR_CHUNKS,
MLXSW_SP_RESOURCE_KVD_LINEAR,
&mlxsw_sp_kvdl_chunks_size_params,
@@ -477,7 +477,7 @@ int mlxsw_sp_kvdl_resources_register(struct devlink *devlink)
return err;
err = devlink_resource_register(devlink, MLXSW_SP_RESOURCE_NAME_KVD_LINEAR_LARGE_CHUNKS,
- false, MLXSW_SP_KVDL_LARGE_CHUNKS_SIZE,
+ MLXSW_SP_KVDL_LARGE_CHUNKS_SIZE,
MLXSW_SP_RESOURCE_KVD_LINEAR_LARGE_CHUNKS,
MLXSW_SP_RESOURCE_KVD_LINEAR,
&mlxsw_sp_kvdl_large_chunks_size_params,
diff --git a/include/net/devlink.h b/include/net/devlink.h
index c83125ad20ff..d5b707375e48 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -406,7 +406,6 @@ extern struct devlink_dpipe_header devlink_dpipe_header_ipv6;
int devlink_resource_register(struct devlink *devlink,
const char *resource_name,
- bool top_hierarchy,
u64 resource_size,
u64 resource_id,
u64 parent_resource_id,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index f23e5ed7c90f..d03b96f87c25 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3174,7 +3174,6 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
*/
int devlink_resource_register(struct devlink *devlink,
const char *resource_name,
- bool top_hierarchy,
u64 resource_size,
u64 resource_id,
u64 parent_resource_id,
@@ -3183,8 +3182,11 @@ int devlink_resource_register(struct devlink *devlink,
{
struct devlink_resource *resource;
struct list_head *resource_list;
+ bool top_hierarchy;
int err = 0;
+ top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
+
mutex_lock(&devlink->lock);
resource = devlink_resource_find(devlink, NULL, resource_id);
if (resource) {
--
2.11.0
^ permalink raw reply related
* pull-request: bpf 2018-03-21
From: Daniel Borkmann @ 2018-03-21 1:50 UTC (permalink / raw)
To: davem; +Cc: daniel, ast, netdev
Hi David,
The following pull-request contains BPF updates for your *net* tree.
The main changes are:
1) Follow-up fix to the fault injection framework to prevent jump
optimization on the kprobe by installing a dummy post-handler,
from Masami.
2) Drop bpf_perf_prog_read_value helper from tracepoint type programs
which was mistakenly added there and would otherwise crash due to
wrong input context, from Yonghong.
3) Fix a crash in BPF fs when compiled with clang. Code appears to
be fine just that clang tries to overly aggressive optimize in
non C conform ways, therefore fix the kernel's Makefile to
generally prevent such issues, from Daniel.
4) Skip unnecessary capability checks in bpf syscall, which is otherwise
triggering unnecessary security hooks on capability checking and
causing false alarms on unprivileged processes trying to access
CAP_SYS_ADMIN restricted infra, from Chenbo.
5) Fix the test_bpf.ko module when CONFIG_BPF_JIT_ALWAYS_ON is set
with regards to a test case that is really just supposed to fail
on x8_64 JIT but not others, from Thadeu.
Please consider pulling these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
Thanks a lot!
----------------------------------------------------------------
The following changes since commit 9e5fb7207024e53700bdac23f53d1e44d530a7f6:
Merge branch 'bnxt_en-Bug-fixes' (2018-03-12 10:58:28 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
for you to fetch changes up to 87e0d4f0f37fb0c8c4aeeac46fff5e957738df79:
kbuild: disable clang's default use of -fmerge-all-constants (2018-03-20 17:43:15 -0700)
----------------------------------------------------------------
Chenbo Feng (1):
bpf: skip unnecessary capability check
Daniel Borkmann (1):
kbuild: disable clang's default use of -fmerge-all-constants
Masami Hiramatsu (1):
error-injection: Fix to prohibit jump optimization
Thadeu Lima de Souza Cascardo (1):
test_bpf: Fix testing with CONFIG_BPF_JIT_ALWAYS_ON=y on other arches
Yonghong Song (1):
trace/bpf: remove helper bpf_perf_prog_read_value from tracepoint type programs
Makefile | 9 +++++++
kernel/bpf/syscall.c | 2 +-
kernel/fail_function.c | 10 +++++++
kernel/trace/bpf_trace.c | 68 ++++++++++++++++++++++++++++--------------------
lib/test_bpf.c | 2 +-
5 files changed, 61 insertions(+), 30 deletions(-)
^ permalink raw reply
* pull-request: bpf-next 2018-03-21
From: Daniel Borkmann @ 2018-03-21 1:29 UTC (permalink / raw)
To: davem; +Cc: daniel, ast, netdev
Hi David,
The following pull-request contains BPF updates for your *net-next* tree.
The main changes are:
1) Add a BPF hook for sendmsg and sendfile by reusing the ULP infrastructure
and sockmap. Three helpers are added along with this, bpf_msg_apply_bytes(),
bpf_msg_cork_bytes(), and bpf_msg_pull_data(). The first is used to tell
for how many bytes the verdict should be applied to, the second to tell
that x bytes need to be queued first to retrigger the BPF program for a
verdict, and the third helper is mainly for the sendfile case to pull in
data for making it private for reading and/or writing, from John.
2) Improve address to symbol resolution of user stack traces in BPF stackmap.
Currently, the latter stores the address for each entry in the call trace,
however to map these addresses to user space files, it is necessary to
maintain the mapping from these virtual addresses to symbols in the binary
which is not practical for system-wide profiling. Instead, this option for
the stackmap rather stores the ELF build id and offset for the call trace
entries, from Song.
3) Add support that allows BPF programs attached to perf events to read the
address values recorded with the perf events. They are requested through
PERF_SAMPLE_ADDR via perf_event_open(). Main motivation behind it is to
support building memory or lock access profiling and tracing tools with
the help of BPF, from Teng.
4) Several improvements to the tools/bpf/ Makefiles. The 'make bpf' in the
tools directory does not provide the standard quiet output except for
bpftool and it also does not respect specifying a build output directory.
'make bpf_install' command neither respects specified destination nor
prefix, all from Jiri. In addition, Jakub fixes several other minor issues
in the Makefiles on top of that, e.g. fixing dependency paths, phony
targets and more.
5) Various doc updates e.g. add a comment for BPF fs about reserved names
to make the dentry lookup from there a bit more obvious, and a comment
to the bpf_devel_QA file in order to explain the diff between native
and bpf target clang usage with regards to pointer size, from Quentin
and Daniel.
Please consider pulling these changes from:
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
Thanks a lot!
----------------------------------------------------------------
The following changes since commit a366e300ae9fc466d333e6d8f2bc5d58ed248041:
ip6mr: remove synchronize_rcu() in favor of SOCK_RCU_FREE (2018-03-07 18:13:41 -0500)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
for you to fetch changes up to 78262f4575c29f185947fe58952cd1beabc74f82:
bpf, doc: add description wrt native/bpf clang target and pointer size (2018-03-20 15:47:45 -0700)
----------------------------------------------------------------
Daniel Borkmann (6):
Merge branch 'bpf-perf-sample-addr'
Merge branch 'bpf-tools-makefile-improvements'
Merge branch 'bpf-stackmap-build-id'
Merge branch 'bpf-tools-build-improvements'
Merge branch 'bpf-sockmap-ulp'
bpf, doc: add description wrt native/bpf clang target and pointer size
Jakub Kicinski (4):
tools: bpftool: fix dependency file path
tools: bpftool: fix potential format truncation
tools: bpf: cleanup PHONY target
tools: bpf: remove feature detection output
Jiri Benc (7):
tools: bpftool: silence 'missing initializer' warnings
tools: bpf: respect output directory during build
tools: bpf: consistent make bpf_install
tools: bpf: make install should build first
tools: bpf: call descend in Makefile
tools: bpf: respect quiet/verbose build
tools: bpf: silence make by not deleting intermediate file
John Fastabend (18):
sock: make static tls function alloc_sg generic sock helper
sockmap: convert refcnt to an atomic refcnt
net: do_tcp_sendpages flag to avoid SKBTX_SHARED_FRAG
net: generalize sk_alloc_sg to work with scatterlist rings
bpf: create tcp_bpf_ulp allowing BPF to monitor socket TX/RX data
bpf: sockmap, add bpf_msg_apply_bytes() helper
bpf: sockmap, add msg_cork_bytes() helper
bpf: sk_msg program helper bpf_sk_msg_pull_data
bpf: add map tests for BPF_PROG_TYPE_SK_MSG
bpf: add verifier tests for BPF_PROG_TYPE_SK_MSG
bpf: sockmap sample, add option to attach SK_MSG program
bpf: sockmap sample, add sendfile test
bpf: sockmap sample, add data verification option
bpf: sockmap, add sample option to test apply_bytes helper
bpf: sockmap sample support for bpf_msg_cork_bytes()
bpf: sockmap add SK_DROP tests
bpf: sockmap sample test for bpf_msg_pull_data
bpf: sockmap test script
Quentin Monnet (1):
bpf: comment why dots in filenames under BPF virtual FS are not allowed
Song Liu (2):
bpf: extend stackmap to save binary_build_id+offset instead of address
bpf: add selftest for stackmap with BPF_F_STACK_BUILD_ID
Teng Qin (2):
bpf: add support to read sample address in bpf program
samples/bpf: add example to test reading address
Documentation/bpf/bpf_devel_QA.txt | 12 +
include/linux/bpf.h | 1 +
include/linux/bpf_types.h | 1 +
include/linux/filter.h | 17 +
include/linux/socket.h | 1 +
include/net/sock.h | 4 +
include/uapi/linux/bpf.h | 47 +-
include/uapi/linux/bpf_perf_event.h | 1 +
kernel/bpf/inode.c | 3 +
kernel/bpf/sockmap.c | 733 ++++++++++++++++++++-
kernel/bpf/stackmap.c | 257 +++++++-
kernel/bpf/syscall.c | 14 +-
kernel/bpf/verifier.c | 5 +-
kernel/trace/bpf_trace.c | 20 +-
net/core/filter.c | 273 +++++++-
net/core/sock.c | 61 ++
net/ipv4/tcp.c | 4 +-
net/tls/tls_sw.c | 69 +-
samples/bpf/bpf_load.c | 8 +-
samples/bpf/trace_event_kern.c | 4 +
samples/bpf/trace_event_user.c | 15 +
samples/sockmap/sockmap_kern.c | 197 ++++++
samples/sockmap/sockmap_test.sh | 450 +++++++++++++
samples/sockmap/sockmap_user.c | 301 ++++++++-
tools/bpf/Makefile | 78 ++-
tools/bpf/bpftool/Makefile | 6 +-
tools/bpf/bpftool/xlated_dumper.h | 2 +-
tools/include/uapi/linux/bpf.h | 47 +-
tools/lib/bpf/libbpf.c | 1 +
tools/testing/selftests/bpf/Makefile | 13 +-
tools/testing/selftests/bpf/bpf_helpers.h | 10 +
tools/testing/selftests/bpf/sockmap_parse_prog.c | 15 +-
tools/testing/selftests/bpf/sockmap_tcp_msg_prog.c | 33 +
tools/testing/selftests/bpf/sockmap_verdict_prog.c | 7 +
tools/testing/selftests/bpf/test_maps.c | 55 +-
tools/testing/selftests/bpf/test_progs.c | 164 ++++-
.../selftests/bpf/test_stacktrace_build_id.c | 60 ++
tools/testing/selftests/bpf/test_verifier.c | 54 ++
tools/testing/selftests/bpf/urandom_read.c | 22 +
39 files changed, 2879 insertions(+), 186 deletions(-)
create mode 100755 samples/sockmap/sockmap_test.sh
create mode 100644 tools/testing/selftests/bpf/sockmap_tcp_msg_prog.c
create mode 100644 tools/testing/selftests/bpf/test_stacktrace_build_id.c
create mode 100644 tools/testing/selftests/bpf/urandom_read.c
^ permalink raw reply
* Re: [net-next] intel: add SPDX identifiers to all the Intel drivers
From: Joe Perches @ 2018-03-21 1:14 UTC (permalink / raw)
To: Jeff Kirsher, Philippe Ombredanne, Allan, Bruce W
Cc: davem@davemloft.net, netdev@vger.kernel.org, nhorman@redhat.com,
sassmann@redhat.com, jogreene@redhat.com, Kate Stewart,
Greg Kroah-Hartman, Thomas Gleixner
In-Reply-To: <1521594560.15055.10.camel@intel.com>
On Tue, 2018-03-20 at 18:09 -0700, Jeff Kirsher wrote:
> On Tue, 2018-03-20 at 16:46 -0700, Philippe Ombredanne wrote:
> > When the kernel maintainers decide to switch to V3.0 of the SPDX list,
> > the doc will be updated and then Joe's script could be applied at once
> > to update the past.
>
> I am fine with changing my patch back to v2.6 SPDX ids, as long as Joe's
> script in the future won't touch the Intel wired LAN drivers, since we need
> to retain copyright on several files through out our drivers.
Why would exempting intel wired drivers be
necessary or useful?
I think it would be better if the kernel
source files used a consistent tag format.
The script I wrote is basically a sed that
simply updates the SPDX license text.
That is not particular different that Thomas's
original script that added the SPDX tags.
I have no intention of claiming anything like
a copyright on the output of a trivial script.
^ permalink raw reply
* Re: linux-next on x60: network manager often complains "network is disabled" after resume
From: Woody Suwalski @ 2018-03-21 1:11 UTC (permalink / raw)
To: Pavel Machek
Cc: Rafael J. Wysocki, kernel list, Linux-pm mailing list,
Netdev list
In-Reply-To: <6e43123a-5227-96c4-a1f5-4416bdb5b0db@gmail.com>
Woody Suwalski wrote:
> Pavel Machek wrote:
>> On Mon 2018-03-19 05:17:45, Woody Suwalski wrote:
>>> Pavel Machek wrote:
>>>> Hi!
>>>>
>>>> With recent linux-next, after resume networkmanager often claims that
>>>> "network is disabled". Sometimes suspend/resume clears that.
>>>>
>>>> Any ideas? Does it work for you?
>>>> Pavel
>>> Tried the 4.16-rc6 with nm 1.4.4 - I do not see the issue.
>> Thanks for testing... but yes, 4.16 should be ok. If not fixed,
>> problem will appear in 4.17-rc1.
>>
> Works here OK. Tried ~10 suspends, all restarted OK.
> kernel next-20180320
> nmcli shows that Wifi always connects OK
>
> Woody
>
Contrary, it just happened to me on a 64-bit build 4.16-rc5 on T440.
I think that Dan's suspicion is correct - it is a snafu in the PM:
trying to hibernate results in a message:
Failed to hibernate system via logind: There's already a shutdown or
sleep operation in progress.
And ps shows "Ds /lib/systemd/systemd-sleep suspend"...
Woody
^ permalink raw reply
* Re: [net-next] intel: add SPDX identifiers to all the Intel drivers
From: Jeff Kirsher @ 2018-03-21 1:09 UTC (permalink / raw)
To: Philippe Ombredanne, Allan, Bruce W
Cc: Joe Perches, davem@davemloft.net, netdev@vger.kernel.org,
nhorman@redhat.com, sassmann@redhat.com, jogreene@redhat.com,
Kate Stewart, Greg Kroah-Hartman, Thomas Gleixner
In-Reply-To: <CAOFm3uGQU1cG0kmi6krA9ui_nHq8ptU0w0nVNUOow7UGErgnag@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2868 bytes --]
On Tue, 2018-03-20 at 16:46 -0700, Philippe Ombredanne wrote:
> Allan,
>
> On Tue, Mar 20, 2018 at 1:48 PM, Allan, Bruce W <bruce.w.allan@intel.com>
> wrote:
> > > -----Original Message-----
> > > From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.o
> > > rg]
> > > On Behalf Of Jeff Kirsher
> > > Sent: Tuesday, March 20, 2018 10:52 AM
> > > To: Joe Perches <joe@perches.com>; davem@davemloft.net; Philippe
> > > Ombredanne <pombredanne@nexb.com>
> > > Cc: netdev@vger.kernel.org; nhorman@redhat.com; sassmann@redhat.com;
> > > jogreene@redhat.com
> > > Subject: Re: [net-next] intel: add SPDX identifiers to all the Intel
> > > drivers
> > >
> > > On Tue, 2018-03-20 at 10:41 -0700, Joe Perches wrote:
> > > > On Tue, 2018-03-20 at 10:13 -0700, Jeff Kirsher wrote:
> > > > > Add the SPDX identifiers to all the Intel wired LAN driver files,
> > > > > as
> > > > > outlined in Documentation/process/license-rules.rst.
> > > >
> > > > So far the Documentation does not show using the -only variant.
> > > >
> > > > For a discussion, please see:
> > > > https://lkml.org/lkml/2018/2/8/311
> >
> > But the Linux Foundation, the authority maintaining the valid SPDX
> > identifiers, indicates at https://spdx.org/licenses/ that "GPL-2.0" is
> > deprecated while "GPL-2.0-only" (and others) is appropriate.
> > Was there any mention in the thread or other conversations if/when the
> > kernel's documentation (and all existing uses of "GPL-2.0" in the
> > kernel) will be updated to "GPL-2.0-only"?
>
> The kernel (as documented by Thomas [1]) is using for now the V2.6 of
> the SPDX licenses list. [2] IMHO the reference should be the kernel
> doc and nothing else to ensure consistency and avoid confusion (which
> obviously was not avoided entirely here ;) ).
>
> What happened is in late December a new version 3 was published by
> SPDX and the v2.6 is no longer online. I will bring this up to the
> SPDX group because we should be able to reference the version 2.6
> online (it is still in git though [2]).
>
> When the kernel maintainers decide to switch to V3.0 of the SPDX list,
> the doc will be updated and then Joe's script could be applied at once
> to update the past.
I am fine with changing my patch back to v2.6 SPDX ids, as long as Joe's
script in the future won't touch the Intel wired LAN drivers, since we need
to retain copyright on several files through out our drivers.
>
> What matters most here is consistency: having some v2.6 and some v3.0
> SPDX ids at once is not a happy thing IMHO.
I understand that having a mix of v2.6 and v3.0 SPDX at once is not a happy
thing.
> [1]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/D
> ocumentation/process/license-rules.rst
> [2] https://github.com/spdx/license-list-data/tree/v2.6
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* [PATCH v2] Bluetooth: Remove VLA usage in aes_cmac
From: Gustavo A. R. Silva @ 2018-03-21 1:05 UTC (permalink / raw)
To: Marcel Holtmann, Johan Hedberg, David S. Miller
Cc: linux-bluetooth, netdev, linux-kernel, Gustavo A. R. Silva
In preparation to enabling -Wvla, remove VLA and replace it
with dynamic memory allocation instead.
The use of stack Variable Length Arrays needs to be avoided, as they
can be a vector for stack exhaustion, which can be both a runtime bug
or a security flaw. Also, in general, as code evolves it is easy to
lose track of how big a VLA can get. Thus, we can end up having runtime
failures that are hard to debug.
Also, fixed as part of the directive to remove all VLAs from
the kernel: https://lkml.org/lkml/2018/3/7/621
Signed-off-by: Gustavo A. R. Silva <garsilva@embeddedor.com>
---
Changes in v2:
- Fix memory leak in previous patch.
net/bluetooth/smp.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index a2ddae2..0fa7035 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -173,7 +173,7 @@ static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
size_t len, u8 mac[16])
{
uint8_t tmp[16], mac_msb[16], msg_msb[CMAC_MSG_MAX];
- SHASH_DESC_ON_STACK(desc, tfm);
+ struct shash_desc *shash;
int err;
if (len > CMAC_MSG_MAX)
@@ -184,8 +184,13 @@ static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
return -EINVAL;
}
- desc->tfm = tfm;
- desc->flags = 0;
+ shash = kzalloc(sizeof(*shash) + crypto_shash_descsize(tfm),
+ GFP_KERNEL);
+ if (!shash)
+ return -ENOMEM;
+
+ shash->tfm = tfm;
+ shash->flags = 0;
/* Swap key and message from LSB to MSB */
swap_buf(k, tmp, 16);
@@ -197,11 +202,13 @@ static int aes_cmac(struct crypto_shash *tfm, const u8 k[16], const u8 *m,
err = crypto_shash_setkey(tfm, tmp, 16);
if (err) {
BT_ERR("cipher setkey failed: %d", err);
+ kfree(shash);
return err;
}
- err = crypto_shash_digest(desc, msg_msb, len, mac_msb);
- shash_desc_zero(desc);
+ err = crypto_shash_digest(shash, msg_msb, len, mac_msb);
+ shash_desc_zero(shash);
+ kfree(shash);
if (err) {
BT_ERR("Hash computation error %d", err);
return err;
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox