Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a11e1d43 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Revert changes to convert to ->poll_mask() and aio IOCB_CMD_POLL



The poll() changes were not well thought out, and completely
unexplained.  They also caused a huge performance regression, because
"->poll()" was no longer a trivial file operation that just called down
to the underlying file operations, but instead did at least two indirect
calls.

Indirect calls are sadly slow now with the Spectre mitigation, but the
performance problem could at least be largely mitigated by changing the
"->get_poll_head()" operation to just have a per-file-descriptor pointer
to the poll head instead.  That gets rid of one of the new indirections.

But that doesn't fix the new complexity that is completely unwarranted
for the regular case.  The (undocumented) reason for the poll() changes
was some alleged AIO poll race fixing, but we don't make the common case
slower and more complex for some uncommon special case, so this all
really needs way more explanations and most likely a fundamental
redesign.

[ This revert is a revert of about 30 different commits, not reverted
  individually because that would just be unnecessarily messy  - Linus ]

Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f5749432
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -441,8 +441,6 @@ prototypes:
	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 *);
@@ -473,7 +471,7 @@ prototypes:
};

locking rules:
	All except for ->poll_mask may block.
	All may block.

->llseek() locking has moved from llseek to the individual llseek
implementations.  If your fs is not using generic_file_llseek, you
@@ -505,9 +503,6 @@ 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 *);
+0 −13
Original line number Diff line number Diff line
@@ -857,8 +857,6 @@ 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 *);
@@ -903,17 +901,6 @@ 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 callers can
  wait on.  Callers need to check the returned events using ->poll_mask
  once woken.  Can return NULL to indicate polling is not supported,
  or any error code using the ERR_PTR convention to indicate that a
  grave error occured and ->poll_mask shall not be called.

  poll_mask: return the mask of EPOLL* 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
+10 −3
Original line number Diff line number Diff line
@@ -1060,12 +1060,19 @@ void af_alg_async_cb(struct crypto_async_request *_req, int err)
}
EXPORT_SYMBOL_GPL(af_alg_async_cb);

__poll_t af_alg_poll_mask(struct socket *sock, __poll_t events)
/**
 * af_alg_poll - poll system call handler
 */
__poll_t af_alg_poll(struct file *file, struct socket *sock,
			 poll_table *wait)
{
	struct sock *sk = sock->sk;
	struct alg_sock *ask = alg_sk(sk);
	struct af_alg_ctx *ctx = ask->private;
	__poll_t mask = 0;
	__poll_t mask;

	sock_poll_wait(file, sk_sleep(sk), wait);
	mask = 0;

	if (!ctx->more || ctx->used)
		mask |= EPOLLIN | EPOLLRDNORM;
@@ -1075,7 +1082,7 @@ __poll_t af_alg_poll_mask(struct socket *sock, __poll_t events)

	return mask;
}
EXPORT_SYMBOL_GPL(af_alg_poll_mask);
EXPORT_SYMBOL_GPL(af_alg_poll);

/**
 * af_alg_alloc_areq - allocate struct af_alg_async_req
+2 −2
Original line number Diff line number Diff line
@@ -375,7 +375,7 @@ static struct proto_ops algif_aead_ops = {
	.sendmsg	=	aead_sendmsg,
	.sendpage	=	af_alg_sendpage,
	.recvmsg	=	aead_recvmsg,
	.poll_mask	=	af_alg_poll_mask,
	.poll		=	af_alg_poll,
};

static int aead_check_key(struct socket *sock)
@@ -471,7 +471,7 @@ static struct proto_ops algif_aead_ops_nokey = {
	.sendmsg	=	aead_sendmsg_nokey,
	.sendpage	=	aead_sendpage_nokey,
	.recvmsg	=	aead_recvmsg_nokey,
	.poll_mask	=	af_alg_poll_mask,
	.poll		=	af_alg_poll,
};

static void *aead_bind(const char *name, u32 type, u32 mask)
+2 −2
Original line number Diff line number Diff line
@@ -206,7 +206,7 @@ static struct proto_ops algif_skcipher_ops = {
	.sendmsg	=	skcipher_sendmsg,
	.sendpage	=	af_alg_sendpage,
	.recvmsg	=	skcipher_recvmsg,
	.poll_mask	=	af_alg_poll_mask,
	.poll		=	af_alg_poll,
};

static int skcipher_check_key(struct socket *sock)
@@ -302,7 +302,7 @@ static struct proto_ops algif_skcipher_ops_nokey = {
	.sendmsg	=	skcipher_sendmsg_nokey,
	.sendpage	=	skcipher_sendpage_nokey,
	.recvmsg	=	skcipher_recvmsg_nokey,
	.poll_mask	=	af_alg_poll_mask,
	.poll		=	af_alg_poll,
};

static void *skcipher_bind(const char *name, u32 type, u32 mask)
Loading