lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sat, 30 Oct 2010 14:48:26 +0900
From:	Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To:	paulmck@...ux.vnet.ibm.com
Cc:	linux-kernel@...r.kernel.org
Subject: Re: Memory barrier question.

Paul E. McKenney wrote:
> For the CPU, let's take it by type of architecture...
> 
> First, let's get the UP-only architectures out of the way.  These would
> always see their changes in order, so woiuld always see "hello".

Of course.

> Second, let's consider the TSO architectures, including x86, SPARC,
> PA-RISC, and IBM Mainframe.  On these architectures, reads are not
> reordered by the CPU, so if they see the new pointer, they will also
> see the new characters -- hence "hello".

Yes.

> Next, let's consider weakly ordered systems that respect dependency
> ordering (ARM, PowerPC, Itanium).  The load of the pointer would
> always be ordered with respect to any dereference of the pointer,
> so they would always see "hello".

I'm relieved to hear that.

> This leave DEC Alpha.  In this architecture, smp_read_barrier_depends()
> expands to smp_rmb(), which forces the ordering as required.  So
> Alpha also sees "hello."

Yes.

> I believe that this covers all of the cases.
> 
> Am I missing anything?

You are right. Regarding list elements, they are appropriately protected.



Then, what about list heads that are dynamically allocated/initialized?

sruct hashed_word {
	struct list_head list;
	void *key;
	char *buf;
};
static struct list_head tables[1u << TABLEBIT];
static void (*some_callback) (void *);

static void init(void)
{
	int i;
	/* Initialize the table. */
	for (i = 0; i < (1u << TABLEBIT); i++)
		INIT_LIST_HEAD(&tables[i]);
	smp_wmb();
	/* Allow other CPUs to access the table. */
	some_callback = func;
}

/*
 * This function is called by
 *
 *	if (some_callback)
 *		some_callback(some_ptr);
 *
 * rather than
 *
 *	func(some_ptr);
 *
 * .
 */
static void func(void *some_ptr)
{
	struct hashed_word *ptr;
	struct list_head *table = &tables[hash_ptr(some_ptr, TABLEBIT)];
	/* We must make sure that readers see table->next != NULL. */
	smp_rmb();
	rcu_read_lock();
	list_for_each_entry_rcu(ptr, table, list) {
		if (ptr->key != some_ptr)
			continue;
		printk("%s\n", ptr->buf);
		break;
	}
	rcu_read_unlock();
}

How can I make sure INIT_LIST_HEAD() in init() takes effect?
Is smp_rmb() appropriate?

Well, I wish we can wait for all CPUs to see table->next != NULL
before proceeding to "some_callback = func;" so that readers are
guaranteed to see table->next != NULL without issuing memory barriers...

Regards.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ