Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (37 commits)
  smc91c92_cs: fix the problem of "Unable to find hardware address"
  r8169: clean up my printk uglyness
  net: Hook up cxgb4 to Kconfig and Makefile
  cxgb4: Add main driver file and driver Makefile
  cxgb4: Add remaining driver headers and L2T management
  cxgb4: Add packet queues and packet DMA code
  cxgb4: Add HW and FW support code
  cxgb4: Add register, message, and FW definitions
  netlabel: Fix several rcu_dereference() calls used without RCU read locks
  bonding: fix potential deadlock in bond_uninit()
  net: check the length of the socket address passed to connect(2)
  stmmac: add documentation for the driver.
  stmmac: fix kconfig for crc32 build error
  be2net: fix bug in vlan rx path for big endian architecture
  be2net: fix flashing on big endian architectures
  be2net: fix a bug in flashing the redboot section
  bonding: bond_xmit_roundrobin() fix
  drivers/net: Add missing unlock
  net: gianfar - align BD ring size console messages
  net: gianfar - initialize per-queue statistics
  ...
This commit is contained in:
Linus Torvalds
2010-04-06 08:34:06 -07:00
47 changed files with 14221 additions and 131 deletions

View File

@@ -51,9 +51,12 @@ struct netlbl_domhsh_tbl {
};
/* Domain hash table */
/* XXX - updates should be so rare that having one spinlock for the entire
* hash table should be okay */
/* updates should be so rare that having one spinlock for the entire hash table
* should be okay */
static DEFINE_SPINLOCK(netlbl_domhsh_lock);
#define netlbl_domhsh_rcu_deref(p) \
rcu_dereference_check(p, rcu_read_lock_held() || \
lockdep_is_held(&netlbl_domhsh_lock))
static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
@@ -107,7 +110,8 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry)
* Description:
* This is the hashing function for the domain hash table, it returns the
* correct bucket number for the domain. The caller is responsibile for
* calling the rcu_read_[un]lock() functions.
* ensuring that the hash table is protected with either a RCU read lock or the
* hash table lock.
*
*/
static u32 netlbl_domhsh_hash(const char *key)
@@ -121,7 +125,7 @@ static u32 netlbl_domhsh_hash(const char *key)
for (iter = 0, val = 0, len = strlen(key); iter < len; iter++)
val = (val << 4 | (val >> (8 * sizeof(u32) - 4))) ^ key[iter];
return val & (rcu_dereference(netlbl_domhsh)->size - 1);
return val & (netlbl_domhsh_rcu_deref(netlbl_domhsh)->size - 1);
}
/**
@@ -131,7 +135,8 @@ static u32 netlbl_domhsh_hash(const char *key)
* Description:
* Searches the domain hash table and returns a pointer to the hash table
* entry if found, otherwise NULL is returned. The caller is responsibile for
* the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
* ensuring that the hash table is protected with either a RCU read lock or the
* hash table lock.
*
*/
static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
@@ -142,7 +147,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
if (domain != NULL) {
bkt = netlbl_domhsh_hash(domain);
bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt];
bkt_list = &netlbl_domhsh_rcu_deref(netlbl_domhsh)->tbl[bkt];
list_for_each_entry_rcu(iter, bkt_list, list)
if (iter->valid && strcmp(iter->domain, domain) == 0)
return iter;
@@ -160,8 +165,8 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
* Searches the domain hash table and returns a pointer to the hash table
* entry if an exact match is found, if an exact match is not present in the
* hash table then the default entry is returned if valid otherwise NULL is
* returned. The caller is responsibile for the rcu hash table locks
* (i.e. the caller much call rcu_read_[un]lock()).
* returned. The caller is responsibile ensuring that the hash table is
* protected with either a RCU read lock or the hash table lock.
*
*/
static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
@@ -170,7 +175,7 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
entry = netlbl_domhsh_search(domain);
if (entry == NULL) {
entry = rcu_dereference(netlbl_domhsh_def);
entry = netlbl_domhsh_rcu_deref(netlbl_domhsh_def);
if (entry != NULL && !entry->valid)
entry = NULL;
}
@@ -307,8 +312,11 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
struct netlbl_af6list *tmp6;
#endif /* IPv6 */
/* XXX - we can remove this RCU read lock as the spinlock protects the
* entire function, but before we do we need to fixup the
* netlbl_af[4,6]list RCU functions to do "the right thing" with
* respect to rcu_dereference() when only a spinlock is held. */
rcu_read_lock();
spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL)
entry_old = netlbl_domhsh_search(entry->domain);

View File

@@ -115,6 +115,9 @@ struct netlbl_unlhsh_walk_arg {
/* updates should be so rare that having one spinlock for the entire
* hash table should be okay */
static DEFINE_SPINLOCK(netlbl_unlhsh_lock);
#define netlbl_unlhsh_rcu_deref(p) \
rcu_dereference_check(p, rcu_read_lock_held() || \
lockdep_is_held(&netlbl_unlhsh_lock))
static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL;
static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL;
@@ -236,15 +239,13 @@ static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
* Description:
* This is the hashing function for the unlabeled hash table, it returns the
* bucket number for the given device/interface. The caller is responsible for
* calling the rcu_read_[un]lock() functions.
* ensuring that the hash table is protected with either a RCU read lock or
* the hash table lock.
*
*/
static u32 netlbl_unlhsh_hash(int ifindex)
{
/* this is taken _almost_ directly from
* security/selinux/netif.c:sel_netif_hasfn() as they do pretty much
* the same thing */
return ifindex & (rcu_dereference(netlbl_unlhsh)->size - 1);
return ifindex & (netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->size - 1);
}
/**
@@ -254,7 +255,8 @@ static u32 netlbl_unlhsh_hash(int ifindex)
* Description:
* Searches the unlabeled connection hash table and returns a pointer to the
* interface entry which matches @ifindex, otherwise NULL is returned. The
* caller is responsible for calling the rcu_read_[un]lock() functions.
* caller is responsible for ensuring that the hash table is protected with
* either a RCU read lock or the hash table lock.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
@@ -264,7 +266,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
struct netlbl_unlhsh_iface *iter;
bkt = netlbl_unlhsh_hash(ifindex);
bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt];
bkt_list = &netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt];
list_for_each_entry_rcu(iter, bkt_list, list)
if (iter->valid && iter->ifindex == ifindex)
return iter;
@@ -272,33 +274,6 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
return NULL;
}
/**
* netlbl_unlhsh_search_iface_def - Search for a matching interface entry
* @ifindex: the network interface
*
* Description:
* Searches the unlabeled connection hash table and returns a pointer to the
* interface entry which matches @ifindex. If an exact match can not be found
* and there is a valid default entry, the default entry is returned, otherwise
* NULL is returned. The caller is responsible for calling the
* rcu_read_[un]lock() functions.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
{
struct netlbl_unlhsh_iface *entry;
entry = netlbl_unlhsh_search_iface(ifindex);
if (entry != NULL)
return entry;
entry = rcu_dereference(netlbl_unlhsh_def);
if (entry != NULL && entry->valid)
return entry;
return NULL;
}
/**
* netlbl_unlhsh_add_addr4 - Add a new IPv4 address entry to the hash table
* @iface: the associated interface entry
@@ -309,8 +284,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface_def(int ifindex)
* Description:
* Add a new address entry into the unlabeled connection hash table using the
* interface entry specified by @iface. On success zero is returned, otherwise
* a negative value is returned. The caller is responsible for calling the
* rcu_read_[un]lock() functions.
* a negative value is returned.
*
*/
static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
@@ -350,8 +324,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
* Description:
* Add a new address entry into the unlabeled connection hash table using the
* interface entry specified by @iface. On success zero is returned, otherwise
* a negative value is returned. The caller is responsible for calling the
* rcu_read_[un]lock() functions.
* a negative value is returned.
*
*/
static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
@@ -392,8 +365,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
* Description:
* Add a new, empty, interface entry into the unlabeled connection hash table.
* On success a pointer to the new interface entry is returned, on failure NULL
* is returned. The caller is responsible for calling the rcu_read_[un]lock()
* functions.
* is returned.
*
*/
static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
@@ -416,10 +388,10 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
if (netlbl_unlhsh_search_iface(ifindex) != NULL)
goto add_iface_failure;
list_add_tail_rcu(&iface->list,
&rcu_dereference(netlbl_unlhsh)->tbl[bkt]);
&netlbl_unlhsh_rcu_deref(netlbl_unlhsh)->tbl[bkt]);
} else {
INIT_LIST_HEAD(&iface->list);
if (rcu_dereference(netlbl_unlhsh_def) != NULL)
if (netlbl_unlhsh_rcu_deref(netlbl_unlhsh_def) != NULL)
goto add_iface_failure;
rcu_assign_pointer(netlbl_unlhsh_def, iface);
}
@@ -549,8 +521,7 @@ unlhsh_add_return:
*
* Description:
* Remove an IP address entry from the unlabeled connection hash table.
* Returns zero on success, negative values on failure. The caller is
* responsible for calling the rcu_read_[un]lock() functions.
* Returns zero on success, negative values on failure.
*
*/
static int netlbl_unlhsh_remove_addr4(struct net *net,
@@ -612,8 +583,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
*
* Description:
* Remove an IP address entry from the unlabeled connection hash table.
* Returns zero on success, negative values on failure. The caller is
* responsible for calling the rcu_read_[un]lock() functions.
* Returns zero on success, negative values on failure.
*
*/
static int netlbl_unlhsh_remove_addr6(struct net *net,
@@ -1548,8 +1518,10 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
struct netlbl_unlhsh_iface *iface;
rcu_read_lock();
iface = netlbl_unlhsh_search_iface_def(skb->skb_iif);
iface = netlbl_unlhsh_search_iface(skb->skb_iif);
if (iface == NULL)
iface = rcu_dereference(netlbl_unlhsh_def);
if (iface == NULL || !iface->valid)
goto unlabel_getattr_nolabel;
switch (family) {
case PF_INET: {