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

Commit bbea9f69 authored by Vadim Lobanov's avatar Vadim Lobanov Committed by Linus Torvalds
Browse files

[PATCH] fdtable: Make fdarray and fdsets equal in size



Currently, each fdtable supports three dynamically-sized arrays of data: the
fdarray and two fdsets.  The code allows the number of fds supported by the
fdarray (fdtable->max_fds) to differ from the number of fds supported by each
of the fdsets (fdtable->max_fdset).

In practice, it is wasteful for these two sizes to differ: whenever we hit a
limit on the smaller-capacity structure, we will reallocate the entire fdtable
and all the dynamic arrays within it, so any delta in the memory used by the
larger-capacity structure will never be touched at all.

Rather than hogging this excess, we shouldn't even allocate it in the first
place, and keep the capacities of the fdarray and the fdsets equal.  This
patch removes fdtable->max_fdset.  As an added bonus, most of the supporting
code becomes simpler.

Signed-off-by: default avatarVadim Lobanov <vlobanov@speakeasy.net>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Dipankar Sarma <dipankar@in.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f3d19c90
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -979,7 +979,7 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
	long timeout;
	int ret = -EINVAL;
	struct fdtable *fdt;
	int max_fdset;
	int max_fds;

	timeout = MAX_SCHEDULE_TIMEOUT;
	if (tvp) {
@@ -1003,9 +1003,9 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,

	rcu_read_lock();
	fdt = files_fdtable(current->files);
	max_fdset = fdt->max_fdset;
	max_fds = fdt->max_fds;
	rcu_read_unlock();
	if (n < 0 || n > max_fdset)
	if (n < 0 || n > max_fds)
		goto out_nofds;

	/*
+1 −1
Original line number Diff line number Diff line
@@ -301,7 +301,7 @@ static void sp_cleanup(void)
	for (;;) {
		unsigned long set;
		i = j * __NFDBITS;
		if (i >= fdt->max_fdset || i >= fdt->max_fds)
		if (i >= fdt->max_fds)
			break;
		set = fdt->open_fds->fds_bits[j++];
		while (set) {
+5 −5
Original line number Diff line number Diff line
@@ -1679,19 +1679,19 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
{
	fd_set_bits fds;
	char *bits;
	int size, max_fdset, ret = -EINVAL;
	int size, max_fds, ret = -EINVAL;
	struct fdtable *fdt;

	if (n < 0)
		goto out_nofds;

	/* max_fdset can increase, so grab it once to avoid race */
	/* max_fds can increase, so grab it once to avoid race */
	rcu_read_lock();
	fdt = files_fdtable(current->files);
	max_fdset = fdt->max_fdset;
	max_fds = fdt->max_fds;
	rcu_read_unlock();
	if (n > max_fdset)
		n = max_fdset;
	if (n > max_fds)
		n = max_fds;

	/*
	 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
+1 −1
Original line number Diff line number Diff line
@@ -783,7 +783,7 @@ static void flush_old_files(struct files_struct * files)
		j++;
		i = j * __NFDBITS;
		fdt = files_fdtable(files);
		if (i >= fdt->max_fds || i >= fdt->max_fdset)
		if (i >= fdt->max_fds)
			break;
		set = fdt->close_on_exec->fds_bits[j];
		if (!set)
+2 −3
Original line number Diff line number Diff line
@@ -77,10 +77,9 @@ repeat:
		start = files->next_fd;

	newfd = start;
	if (start < fdt->max_fdset) {
	if (start < fdt->max_fds)
		newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
			fdt->max_fdset, start);
	}
					   fdt->max_fds, start);
	
	error = -EMFILE;
	if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
Loading