All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rusty Russell <rusty@rustcorp.com.au>
To: "Tiago Sant' Anna" <sapuglha@yahoo.com.br>
Cc: sisopiii-l@cscience.org, linux-kernel@vger.kernel.org,
	julianofs@pop.com.br
Subject: Re: New feature: Removal of the exceptions wich belongs to the init section
Date: Mon, 01 Dec 2003 17:03:09 +1100	[thread overview]
Message-ID: <20031201091853.2EC342C01B@lists.samba.org> (raw)
In-Reply-To: Your message of "Fri, 28 Nov 2003 15:58:53 -0200." <20031128155853.33283fec.sapuglha@yahoo.com.br>

In message <20031128155853.33283fec.sapuglha@yahoo.com.br> you write:
> Hello Rusty,

Hi,

> We, Juliano (julianofs@pop.com.br) and I (Tiago Sant' Anna
> (sapuglha@yahoo.com.br) developed this patch.

	I've commented on your patch: I hope you find my feedback
useful.

> diff -Nur linux-2.6.0-test9-vanilla/arch/alpha/mm/extable.c linux-2.6.0-test9-modified/arch/alpha/mm/extable.c
> --- linux-2.6.0-test9-vanilla/arch/alpha/mm/extable.c	2003-10-25 16:42:52.000000000 -0200
> +++ linux-2.6.0-test9-modified/arch/alpha/mm/extable.c	2003-11-28 10:43:18.000000000 -0200
> @@ -27,3 +27,18 @@
>  
>          return NULL;
>  }

It's generally not a good idea to write code for architectures which
you don't have access to, but to leave them for arch maintainers to
sort out.

> +/* Exception_table_entry Comparison. Only the field insn is considered. 
> +   Results:
> +	equal: 0
> +	ex1 less than ex2: -1
> +	ex1 major than ex2: 1
> +*/

This comment is a little verbose: I would simply say:

/* Compare two exception table entries: < 0 if ex1 comes before ex2. */

> +int extable_cmp(const struct exception_table_entry ex1, const struct exception_table_entry ex2) {
> +	
> +	if (ex1.insn < ex2.insn)
> +		return(-1);
> +	else if (ex1.insn > ex2.insn)
> +		return(1);
> +	return(0);
> +}

And it can be implemented as "return (long)ex1.insn - ex2.insn;",
making it a candidate for an inline function in the asm/uaccess.h
header.

> +/* Verify if the addr belongs to the init section */
> +static inline int within_mod_init_section(unsigned long addr, 
> +                                          void *start, unsigned long size)
> +{
> +	    return ((void *)addr >= start && (void *)addr < start + size);
> +}
> +
> +/* Remove exception table entries that point to init area.
> + * It will be used in the unload of init section.
> + */
> +void remove_init_exceptions(struct module *mod) {

This comment is not quite true.  The exception entries themselves are
in the __ex_table section, which is in the module code.  Some of the
"insn" pointers are into the module init section, which is to be
discarded.

This function should be in kernel/extable.c.

> +
> +	static spinlock_t init_ex_remove = SPIN_LOCK_UNLOCKED;

Do not invent your own lock.  You only need to protect against the
exception table walk by other CPUs, for which modlist_lock is
sufficient.

> +
> +	const struct exception_table_entry *local;
> +	unsigned int i;
> +	int num_init_ex=0;
> +
> +
> +	local = mod->extable;
> +	i = 1;
> +
> +	while (i <= mod->num_exentries) {
> +		if (within_mod_init_section((unsigned long) local->insn, mod->module_init, mod->init_size)) {
> +			num_init_ex++;			
> +		}
> +		else break;
> +		local = local+1;
> +		i++;
> +	}
> +
> +	local = mod->extable;

This code is incorrect.  The init section could be before or after the
core section, meaning that all the init-related exceptions will be at
the start, or at the end.  So, the code would look like this:

void remove_init_exceptions(struct module *mod)
{
	int i;

	if (!mod->module_init)
		return;

	spin_lock(&modlist_lock);
	if (mod->module_init > mod->module_core) {
		/* init exception entries at the end.  Trim */
		for (i = mod->num_exentries-1; i >= 0; i--)
			if (within(mod->extable[i].insn,
				   mod->module_init, mod->init_size))
				mod->num_exentries--;
	} else {
		/* init exception entries at the start.  Move ptr. */
		for (i = 0; i < mod->num_exentries; i++) {
			if (!within(mod->extable[i].insn,
				    mod->module_init, mod->init_size))
				break;
		}
		mod->extable += i;
		mod->num_exentries -= i;
	}
	spin_nulock(&modlist_lock);
}
		
> +	/* Unload the init exceptions */
> +	for(i=0; i < num_init_ex; ++i)
> +		kfree(local+i);

This doesn't make sense: these are not pointers, but are part of
module->core!  They will be freed in the normal way.

>  /* Free memory returned from module_alloc */
>  void module_free(struct module *mod, void *module_region)
> -{
> +{	
> +	/* Remove exception entries of the init section */
> +	if (module_region == mod->module_init) {
> +		remove_init_exceptions(mod);
> +	}
> +	

Call this from kernel/module.c directly.

> +++ linux-2.6.0-test9-modified/include/linux/extable.h	2003-11-28 10:4
0:57.000000000 -0200
> @@ -0,0 +1,51 @@
> +#ifndef _EXTABLE_H
> +#define _EXTABLE_H
> +
> +/*
> + * Functions regarding to exception's table.
> + *
> + *	* Written by Juliano Silva and Tiago Silva, 2003
> + *	
> + **/
> +
> +
> +#include <linux/module.h>
> +#include <asm/uaccess.h>
> +#include <asm/sections.h>
> +#include <linux/init.h>
> + 
> +/* Exception_table_entry Comparison. Only the field insn is considered.
> + *   Results:
> + *            equal: 0
> + *            ex1 less than ex2: -1
> + *            ex1 major than ex2: 1
> + *                                                         */
> +extern int extable_cmp(struct exception_table_entry ex1,
> +                       struct exception_table_entry ex2);
> +
> +/* This code sorts an exception table. It is very used with modules code 
> + * void __init_or_module sort_ex_table(struct exception_table_entry *start,
> + * struct exception_table_entry *finish);
> + */
> +void __init_or_module sort_ex_table(struct exception_table_entry *start, struct exception_table_entry *finish)

Never put non-inline functions in a header file.  And never inline a
function this large.

Since this is only called from module.c, perhaps put it in
include/linux/moduleloader.h and the code in extable.c.

Hope that helps,
Rusty.
--
  Anyone who quotes me in their sig is an idiot. -- Rusty Russell.

  reply	other threads:[~2003-12-01  9:18 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-11-28 17:58 New feature: Removal of the exceptions wich belongs to the init section Tiago Sant' Anna
2003-12-01  6:03 ` Rusty Russell [this message]
2003-12-17 17:10   ` [PATCH] " Juliano F Silva
2003-12-17 17:17     ` Tiago Sant' Anna

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20031201091853.2EC342C01B@lists.samba.org \
    --to=rusty@rustcorp.com.au \
    --cc=julianofs@pop.com.br \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sapuglha@yahoo.com.br \
    --cc=sisopiii-l@cscience.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.