[RFC PATCH 23/30] rwlock: Prepare write_[un]lock_bh() for handling softirq mask

From: Frederic Weisbecker
Date: Wed Oct 10 2018 - 19:13:52 EST


From: Frederic Weisbecker <fweisbec@xxxxxxxxx>

This pair of function is implemented on top of __local_bh_disable_ip()
that is going to handle a softirq mask in order to apply finegrained
vector disablement. The lock function is going to return the previous
vectors enabled mask prior to the last call to local_bh_disable(),
following a similar model to that of local_irq_save/restore. Subsequent
calls to local_bh_disable() and friends can then stack up:

bh = local_bh_disable(vec_mask);
bh2 = write_lock_bh(...);
...
write_unlock_bh(..., bh2);
local_bh_enable(bh);

To prepare for that, make write_lock_bh() able to return a saved vector
enabled mask and pass it back to write_unlock_bh(). We'll plug it to
__local_bh_disable_ip() in a subsequent patch.

Thanks to coccinelle that helped a lot with scripts such as the
following:

@rw exists@
identifier func;
expression e;
@@
func(...) {
+ unsigned int bh;
...
- write_lock_bh(e);
+ bh = write_lock_bh(e);
...
- write_unlock_bh(e);
+ write_unlock_bh(e, bh);
...
}

Signed-off-by: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: David S. Miller <davem@xxxxxxxxxxxxx>
Cc: Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxxxxx>
Cc: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx>
---
drivers/block/drbd/drbd_receiver.c | 10 +-
drivers/infiniband/core/roce_gid_mgmt.c | 5 +-
drivers/infiniband/hw/cxgb4/cm.c | 5 +-
drivers/isdn/mISDN/socket.c | 17 +--
drivers/isdn/mISDN/stack.c | 10 +-
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 17 +--
drivers/net/ethernet/chelsio/cxgb3/l2t.c | 10 +-
drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c | 41 +++---
drivers/net/ethernet/chelsio/cxgb4/l2t.c | 17 +--
drivers/net/ethernet/chelsio/cxgb4/smt.c | 5 +-
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 5 +-
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 10 +-
.../net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 +-
.../net/ethernet/mellanox/mlxsw/spectrum_span.c | 5 +-
drivers/net/hamradio/6pack.c | 5 +-
drivers/net/hamradio/mkiss.c | 5 +-
drivers/net/ieee802154/fakelb.c | 20 +--
drivers/net/ppp/ppp_generic.c | 35 +++---
drivers/net/ppp/pppoe.c | 24 ++--
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 5 +-
.../net/wireless/intersil/hostap/hostap_80211_rx.c | 5 +-
drivers/net/wireless/intersil/hostap/hostap_main.c | 12 +-
drivers/net/wireless/intersil/hostap/hostap_proc.c | 2 +-
drivers/s390/net/netiucv.c | 36 +++---
drivers/s390/net/qeth_l3_main.c | 10 +-
drivers/scsi/bnx2i/bnx2i_iscsi.c | 45 ++++---
drivers/scsi/cxgbi/libcxgbi.c | 15 ++-
drivers/scsi/iscsi_tcp.c | 31 +++--
.../vc04_services/interface/vchiq_arm/vchiq_arm.c | 69 +++++-----
drivers/target/iscsi/iscsi_target_nego.c | 60 +++++----
drivers/tty/hvc/hvc_iucv.c | 10 +-
drivers/xen/pvcalls-back.c | 20 +--
fs/dlm/lowcomms.c | 40 +++---
fs/ocfs2/cluster/tcp.c | 35 +++---
include/linux/rwlock.h | 8 +-
include/linux/rwlock_api_smp.h | 30 +++--
include/linux/spinlock_api_up.h | 2 +-
include/net/ping.h | 1 +
include/net/sock.h | 10 +-
kernel/bpf/reuseport_array.c | 22 ++--
kernel/bpf/sockmap.c | 20 +--
kernel/locking/spinlock.c | 26 ++--
net/6lowpan/ndisc.c | 12 +-
net/appletalk/aarp.c | 48 ++++---
net/appletalk/atalk_proc.c | 6 +-
net/appletalk/ddp.c | 65 ++++++----
net/atm/mpc.c | 5 +-
net/atm/mpoa_caches.c | 41 +++---
net/ax25/ax25_iface.c | 15 ++-
net/ax25/ax25_route.c | 33 ++---
net/bridge/netfilter/ebtables.c | 32 ++---
net/core/dev.c | 19 +--
net/core/link_watch.c | 5 +-
net/core/neighbour.c | 139 ++++++++++++---------
net/core/netpoll.c | 5 +-
net/core/pktgen.c | 5 +-
net/core/rtnetlink.c | 10 +-
net/core/skbuff.c | 5 +-
net/core/sock.c | 10 +-
net/decnet/af_decnet.c | 20 +--
net/decnet/dn_table.c | 27 ++--
net/hsr/hsr_device.c | 7 +-
net/ieee802154/6lowpan/tx.c | 5 +-
net/ieee802154/socket.c | 20 +--
net/ipv4/arp.c | 10 +-
net/ipv4/ipmr.c | 17 +--
net/ipv4/ping.c | 22 ++--
net/ipv4/raw.c | 10 +-
net/ipv6/addrconf.c | 120 ++++++++++--------
net/ipv6/anycast.c | 38 +++---
net/ipv6/ip6_fib.c | 10 +-
net/ipv6/ip6mr.c | 27 ++--
net/ipv6/ipv6_sockglue.c | 11 +-
net/ipv6/mcast.c | 128 +++++++++++--------
net/ipv6/ndisc.c | 17 +--
net/ipv6/netfilter/nf_tproxy_ipv6.c | 5 +-
net/iucv/af_iucv.c | 20 +--
net/kcm/kcmsock.c | 24 ++--
net/l2tp/l2tp_core.c | 33 ++---
net/l2tp/l2tp_debugfs.c | 5 +-
net/l2tp/l2tp_ip.c | 29 +++--
net/l2tp/l2tp_ip6.c | 29 +++--
net/lapb/lapb_iface.c | 15 ++-
net/mac802154/llsec.c | 31 +++--
net/netfilter/ipset/ip_set_core.c | 45 ++++---
net/netfilter/ipvs/ip_vs_conn.c | 8 +-
net/netfilter/nf_conntrack_proto_gre.c | 27 ++--
net/netfilter/nf_log_common.c | 5 +-
net/netfilter/nf_nat_redirect.c | 5 +-
net/netfilter/nfnetlink_log.c | 7 +-
net/netfilter/nfnetlink_queue.c | 12 +-
net/netfilter/nft_meta.c | 13 +-
net/netfilter/nft_set_rbtree.c | 32 +++--
net/rds/tcp.c | 10 +-
net/rds/tcp_connect.c | 5 +-
net/rds/tcp_listen.c | 15 ++-
net/rds/tcp_recv.c | 5 +-
net/rds/tcp_send.c | 5 +-
net/rxrpc/ar-internal.h | 15 ++-
net/rxrpc/call_accept.c | 12 +-
net/rxrpc/call_object.c | 5 +-
net/rxrpc/conn_client.c | 5 +-
net/rxrpc/conn_event.c | 5 +-
net/rxrpc/recvmsg.c | 26 ++--
net/rxrpc/sendmsg.c | 10 +-
net/sctp/ipv6.c | 5 +-
net/sctp/proc.c | 5 +-
net/sctp/socket.c | 5 +-
net/smc/af_smc.c | 10 +-
net/smc/smc_cdc.c | 5 +-
net/smc/smc_core.c | 41 +++---
net/sunrpc/xprtsock.c | 45 ++++---
net/tipc/monitor.c | 54 ++++----
net/tipc/node.c | 14 ++-
net/tipc/topsrv.c | 35 +++---
net/tls/tls_sw.c | 10 +-
net/x25/af_x25.c | 45 ++++---
net/x25/x25_forward.c | 25 ++--
net/x25/x25_link.c | 30 +++--
net/x25/x25_proc.c | 6 +-
net/x25/x25_route.c | 25 ++--
net/xfrm/xfrm_policy.c | 7 +-
122 files changed, 1494 insertions(+), 1050 deletions(-)

diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 75f6b47..a763105 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -704,6 +704,7 @@ static void drbd_incoming_connection(struct sock *sk)

static int prepare_listen_socket(struct drbd_connection *connection, struct accept_wait_data *ad)
{
+ unsigned int bh;
int err, sndbuf_size, rcvbuf_size, my_addr_len;
struct sockaddr_in6 my_addr;
struct socket *s_listen;
@@ -740,11 +741,11 @@ static int prepare_listen_socket(struct drbd_connection *connection, struct acce
goto out;

ad->s_listen = s_listen;
- write_lock_bh(&s_listen->sk->sk_callback_lock);
+ bh = write_lock_bh(&s_listen->sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
ad->original_sk_state_change = s_listen->sk->sk_state_change;
s_listen->sk->sk_state_change = drbd_incoming_connection;
s_listen->sk->sk_user_data = ad;
- write_unlock_bh(&s_listen->sk->sk_callback_lock);
+ write_unlock_bh(&s_listen->sk->sk_callback_lock, bh);

what = "listen";
err = s_listen->ops->listen(s_listen, 5);
@@ -767,10 +768,11 @@ static int prepare_listen_socket(struct drbd_connection *connection, struct acce

static void unregister_state_change(struct sock *sk, struct accept_wait_data *ad)
{
- write_lock_bh(&sk->sk_callback_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sk->sk_state_change = ad->original_sk_state_change;
sk->sk_user_data = NULL;
- write_unlock_bh(&sk->sk_callback_lock);
+ write_unlock_bh(&sk->sk_callback_lock, bh);
}

static struct socket *drbd_wait_for_connect(struct drbd_connection *connection, struct accept_wait_data *ad)
diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c
index ee36619..d1ed810 100644
--- a/drivers/infiniband/core/roce_gid_mgmt.c
+++ b/drivers/infiniband/core/roce_gid_mgmt.c
@@ -370,6 +370,7 @@ static void enum_netdev_ipv4_ips(struct ib_device *ib_dev,
static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
u8 port, struct net_device *ndev)
{
+ unsigned int bh;
struct inet6_ifaddr *ifp;
struct inet6_dev *in6_dev;
struct sin6_list {
@@ -388,7 +389,7 @@ static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
if (!in6_dev)
return;

- read_lock_bh(&in6_dev->lock);
+ bh = read_lock_bh(&in6_dev->lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
struct sin6_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);

@@ -399,7 +400,7 @@ static void enum_netdev_ipv6_ips(struct ib_device *ib_dev,
entry->sin6.sin6_addr = ifp->addr;
list_add_tail(&entry->list, &sin6_list);
}
- read_unlock_bh(&in6_dev->lock);
+ read_unlock_bh(&in6_dev->lock, bh);

in6_dev_put(in6_dev);

diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 0f83cbe..e064387 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -3163,6 +3163,7 @@ static int pick_local_ipaddrs(struct c4iw_dev *dev, struct iw_cm_id *cm_id)
static int get_lladdr(struct net_device *dev, struct in6_addr *addr,
unsigned char banned_flags)
{
+ unsigned int bh;
struct inet6_dev *idev;
int err = -EADDRNOTAVAIL;

@@ -3171,7 +3172,7 @@ static int get_lladdr(struct net_device *dev, struct in6_addr *addr,
if (idev != NULL) {
struct inet6_ifaddr *ifp;

- read_lock_bh(&idev->lock);
+ bh = read_lock_bh(&idev->lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(ifp, &idev->addr_list, if_list) {
if (ifp->scope == IFA_LINK &&
!(ifp->flags & banned_flags)) {
@@ -3180,7 +3181,7 @@ static int get_lladdr(struct net_device *dev, struct in6_addr *addr,
break;
}
}
- read_unlock_bh(&idev->lock);
+ read_unlock_bh(&idev->lock, bh);
}
rcu_read_unlock();
return err;
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index 18c0a12..2c83d3d 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -54,16 +54,18 @@ _l2_alloc_skb(unsigned int len, gfp_t gfp_mask)
static void
mISDN_sock_link(struct mISDN_sock_list *l, struct sock *sk)
{
- write_lock_bh(&l->lock);
+ unsigned int bh;
+ bh = write_lock_bh(&l->lock, SOFTIRQ_ALL_MASK);
sk_add_node(sk, &l->head);
- write_unlock_bh(&l->lock);
+ write_unlock_bh(&l->lock, bh);
}

static void mISDN_sock_unlink(struct mISDN_sock_list *l, struct sock *sk)
{
- write_lock_bh(&l->lock);
+ unsigned int bh;
+ bh = write_lock_bh(&l->lock, SOFTIRQ_ALL_MASK);
sk_del_node_init(sk);
- write_unlock_bh(&l->lock);
+ write_unlock_bh(&l->lock, bh);
}

static int
@@ -474,6 +476,7 @@ static int data_sock_getsockopt(struct socket *sock, int level, int optname,
static int
data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
+ unsigned int bh;
struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
struct sock *sk = sock->sk;
struct sock *csk;
@@ -499,7 +502,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
}

if (sk->sk_protocol < ISDN_P_B_START) {
- read_lock_bh(&data_sockets.lock);
+ bh = read_lock_bh(&data_sockets.lock, SOFTIRQ_ALL_MASK);
sk_for_each(csk, &data_sockets.head) {
if (sk == csk)
continue;
@@ -510,11 +513,11 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
if (IS_ISDN_P_TE(csk->sk_protocol)
== IS_ISDN_P_TE(sk->sk_protocol))
continue;
- read_unlock_bh(&data_sockets.lock);
+ read_unlock_bh(&data_sockets.lock, bh);
err = -EBUSY;
goto done;
}
- read_unlock_bh(&data_sockets.lock);
+ read_unlock_bh(&data_sockets.lock, bh);
}

_pms(sk)->ch.send = mISDN_send;
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index d97c6dd..fafa705 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -428,6 +428,7 @@ int
connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
u_int protocol, struct sockaddr_mISDN *adr)
{
+ unsigned int bh;
struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
struct channel_req rq;
int err;
@@ -452,9 +453,9 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
dev->id);
if (err)
return err;
- write_lock_bh(&dev->D.st->l1sock.lock);
+ bh = write_lock_bh(&dev->D.st->l1sock.lock, SOFTIRQ_ALL_MASK);
sk_add_node(&msk->sk, &dev->D.st->l1sock.head);
- write_unlock_bh(&dev->D.st->l1sock.lock);
+ write_unlock_bh(&dev->D.st->l1sock.lock, bh);
break;
default:
return -ENOPROTOOPT;
@@ -572,6 +573,7 @@ create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
void
delete_channel(struct mISDNchannel *ch)
{
+ unsigned int bh;
struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
struct mISDNchannel *pch;

@@ -594,9 +596,9 @@ delete_channel(struct mISDNchannel *ch)
case ISDN_P_TE_S0:
case ISDN_P_NT_E1:
case ISDN_P_TE_E1:
- write_lock_bh(&ch->st->l1sock.lock);
+ bh = write_lock_bh(&ch->st->l1sock.lock, SOFTIRQ_ALL_MASK);
sk_del_node_init(&msk->sk);
- write_unlock_bh(&ch->st->l1sock.lock);
+ write_unlock_bh(&ch->st->l1sock.lock, bh);
ch->st->dev->D.ctrl(&ch->st->dev->D, CLOSE_CHANNEL, NULL);
break;
case ISDN_P_LAPD_TE:
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 10a1520..26a2b4d 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -1061,19 +1061,20 @@ EXPORT_SYMBOL(cxgb3_ofld_send);

static int is_offloading(struct net_device *dev)
{
+ unsigned int bh;
struct adapter *adapter;
int i;

- read_lock_bh(&adapter_list_lock);
+ bh = read_lock_bh(&adapter_list_lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(adapter, &adapter_list, adapter_list) {
for_each_port(adapter, i) {
if (dev == adapter->port[i]) {
- read_unlock_bh(&adapter_list_lock);
+ read_unlock_bh(&adapter_list_lock, bh);
return 1;
}
}
}
- read_unlock_bh(&adapter_list_lock);
+ read_unlock_bh(&adapter_list_lock, bh);
return 0;
}

@@ -1209,16 +1210,18 @@ static void free_tid_maps(struct tid_info *t)

static inline void add_adapter(struct adapter *adap)
{
- write_lock_bh(&adapter_list_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&adapter_list_lock, SOFTIRQ_ALL_MASK);
list_add_tail(&adap->adapter_list, &adapter_list);
- write_unlock_bh(&adapter_list_lock);
+ write_unlock_bh(&adapter_list_lock, bh);
}

static inline void remove_adapter(struct adapter *adap)
{
- write_lock_bh(&adapter_list_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&adapter_list_lock, SOFTIRQ_ALL_MASK);
list_del(&adap->adapter_list);
- write_unlock_bh(&adapter_list_lock);
+ write_unlock_bh(&adapter_list_lock, bh);
}

int cxgb3_offload_activate(struct adapter *adapter)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.c b/drivers/net/ethernet/chelsio/cxgb3/l2t.c
index 1e2d466..3c27b94 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.c
@@ -305,6 +305,7 @@ static inline void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct dst_entry *dst,
struct net_device *dev, const void *daddr)
{
+ unsigned int bh;
struct l2t_entry *e = NULL;
struct neighbour *neigh;
struct port_info *p;
@@ -333,7 +334,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct dst_entry *dst,

hash = arp_hash(addr, ifidx, d);

- write_lock_bh(&d->lock);
+ bh = write_lock_bh(&d->lock, SOFTIRQ_ALL_MASK);
for (e = d->l2tab[hash].first; e; e = e->next)
if (e->addr == addr && e->ifindex == ifidx &&
e->smt_idx == smt_idx) {
@@ -362,7 +363,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct dst_entry *dst,
spin_unlock(&e->lock);
}
done_unlock:
- write_unlock_bh(&d->lock);
+ write_unlock_bh(&d->lock, bh);
done_rcu:
if (neigh)
neigh_release(neigh);
@@ -401,6 +402,7 @@ static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff_head *ar
*/
void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh)
{
+ unsigned int bh;
struct sk_buff_head arpq;
struct l2t_entry *e;
struct l2t_data *d = L2DATA(dev);
@@ -408,13 +410,13 @@ void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh)
int ifidx = neigh->dev->ifindex;
int hash = arp_hash(addr, ifidx, d);

- read_lock_bh(&d->lock);
+ bh = read_lock_bh(&d->lock, SOFTIRQ_ALL_MASK);
for (e = d->l2tab[hash].first; e; e = e->next)
if (e->addr == addr && e->ifindex == ifidx) {
spin_lock(&e->lock);
goto found;
}
- read_unlock_bh(&d->lock);
+ read_unlock_bh(&d->lock, bh);
return;

found:
diff --git a/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c b/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c
index 33314fe..a3da529 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c
@@ -73,6 +73,8 @@ static int clip6_release_mbox(const struct net_device *dev,

int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
{
+ unsigned int bh;
+ unsigned int bh;
struct adapter *adap = netdev2adap(dev);
struct clip_tbl *ctbl = adap->clipt;
struct clip_entry *ce, *cte;
@@ -85,7 +87,7 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)

hash = clip_addr_hash(ctbl, addr, v6);

- read_lock_bh(&ctbl->lock);
+ bh = read_lock_bh(&ctbl->lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(cte, &ctbl->hash_list[hash], list) {
if (cte->addr6.sin6_family == AF_INET6 && v6)
ret = memcmp(lip, cte->addr6.sin6_addr.s6_addr,
@@ -95,14 +97,14 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
sizeof(struct in_addr));
if (!ret) {
ce = cte;
- read_unlock_bh(&ctbl->lock);
+ read_unlock_bh(&ctbl->lock, bh);
refcount_inc(&ce->refcnt);
return 0;
}
}
- read_unlock_bh(&ctbl->lock);
+ read_unlock_bh(&ctbl->lock, bh);

- write_lock_bh(&ctbl->lock);
+ bh = write_lock_bh(&ctbl->lock, SOFTIRQ_ALL_MASK);
if (!list_empty(&ctbl->ce_free_head)) {
ce = list_first_entry(&ctbl->ce_free_head,
struct clip_entry, list);
@@ -118,7 +120,7 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
lip, sizeof(struct in6_addr));
ret = clip6_get_mbox(dev, (const struct in6_addr *)lip);
if (ret) {
- write_unlock_bh(&ctbl->lock);
+ write_unlock_bh(&ctbl->lock, bh);
dev_err(adap->pdev_dev,
"CLIP FW cmd failed with error %d, "
"Connections using %pI6c wont be "
@@ -132,13 +134,13 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
sizeof(struct in_addr));
}
} else {
- write_unlock_bh(&ctbl->lock);
+ write_unlock_bh(&ctbl->lock, bh);
dev_info(adap->pdev_dev, "CLIP table overflow, "
"Connections using %pI6c wont be offloaded",
(void *)lip);
return -ENOMEM;
}
- write_unlock_bh(&ctbl->lock);
+ write_unlock_bh(&ctbl->lock, bh);
refcount_set(&ce->refcnt, 1);
return 0;
}
@@ -147,6 +149,7 @@ EXPORT_SYMBOL(cxgb4_clip_get);
void cxgb4_clip_release(const struct net_device *dev, const u32 *lip, u8 v6)
{
unsigned int bh;
+ unsigned int bh2;
struct adapter *adap = netdev2adap(dev);
struct clip_tbl *ctbl = adap->clipt;
struct clip_entry *ce, *cte;
@@ -159,7 +162,7 @@ void cxgb4_clip_release(const struct net_device *dev, const u32 *lip, u8 v6)

hash = clip_addr_hash(ctbl, addr, v6);

- read_lock_bh(&ctbl->lock);
+ bh = read_lock_bh(&ctbl->lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(cte, &ctbl->hash_list[hash], list) {
if (cte->addr6.sin6_family == AF_INET6 && v6)
ret = memcmp(lip, cte->addr6.sin6_addr.s6_addr,
@@ -169,16 +172,16 @@ void cxgb4_clip_release(const struct net_device *dev, const u32 *lip, u8 v6)
sizeof(struct in_addr));
if (!ret) {
ce = cte;
- read_unlock_bh(&ctbl->lock);
+ read_unlock_bh(&ctbl->lock, bh);
goto found;
}
}
- read_unlock_bh(&ctbl->lock);
+ read_unlock_bh(&ctbl->lock, bh);

return;
found:
- write_lock_bh(&ctbl->lock);
- bh = spin_lock_bh(&ce->lock, SOFTIRQ_ALL_MASK);
+ bh = write_lock_bh(&ctbl->lock, SOFTIRQ_ALL_MASK);
+ bh2 = spin_lock_bh(&ce->lock, SOFTIRQ_ALL_MASK);
if (refcount_dec_and_test(&ce->refcnt)) {
list_del(&ce->list);
INIT_LIST_HEAD(&ce->list);
@@ -187,8 +190,8 @@ void cxgb4_clip_release(const struct net_device *dev, const u32 *lip, u8 v6)
if (v6)
clip6_release_mbox(dev, (const struct in6_addr *)lip);
}
- spin_unlock_bh(&ce->lock, bh);
- write_unlock_bh(&ctbl->lock);
+ spin_unlock_bh(&ce->lock, bh2);
+ write_unlock_bh(&ctbl->lock, bh);
}
EXPORT_SYMBOL(cxgb4_clip_release);

@@ -199,6 +202,7 @@ EXPORT_SYMBOL(cxgb4_clip_release);
static int cxgb4_update_dev_clip(struct net_device *root_dev,
struct net_device *dev)
{
+ unsigned int bh;
struct inet6_dev *idev = NULL;
struct inet6_ifaddr *ifa;
int ret = 0;
@@ -207,13 +211,13 @@ static int cxgb4_update_dev_clip(struct net_device *root_dev,
if (!idev)
return ret;

- read_lock_bh(&idev->lock);
+ bh = read_lock_bh(&idev->lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(ifa, &idev->addr_list, if_list) {
ret = cxgb4_clip_get(dev, (const u32 *)ifa->addr.s6_addr, 1);
if (ret < 0)
break;
}
- read_unlock_bh(&idev->lock);
+ read_unlock_bh(&idev->lock, bh);

return ret;
}
@@ -252,13 +256,14 @@ EXPORT_SYMBOL(cxgb4_update_root_dev_clip);

int clip_tbl_show(struct seq_file *seq, void *v)
{
+ unsigned int bh;
struct adapter *adapter = seq->private;
struct clip_tbl *ctbl = adapter->clipt;
struct clip_entry *ce;
char ip[60];
int i;

- read_lock_bh(&ctbl->lock);
+ bh = read_lock_bh(&ctbl->lock, SOFTIRQ_ALL_MASK);

seq_puts(seq, "IP Address Users\n");
for (i = 0 ; i < ctbl->clipt_size; ++i) {
@@ -271,7 +276,7 @@ int clip_tbl_show(struct seq_file *seq, void *v)
}
seq_printf(seq, "Free clip entries : %d\n", atomic_read(&ctbl->nfree));

- read_unlock_bh(&ctbl->lock);
+ read_unlock_bh(&ctbl->lock, bh);

return 0;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
index 3653fd0..7cf1976 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c
@@ -422,6 +422,7 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
const struct net_device *physdev,
unsigned int priority)
{
+ unsigned int bh;
u8 lport;
u16 vlan;
struct l2t_entry *e;
@@ -440,7 +441,7 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
else
vlan = VLAN_NONE;

- write_lock_bh(&d->lock);
+ bh = write_lock_bh(&d->lock, SOFTIRQ_ALL_MASK);
for (e = d->l2tab[hash].first; e; e = e->next)
if (!addreq(e, addr) && e->ifindex == ifidx &&
e->vlan == vlan && e->lport == lport) {
@@ -470,7 +471,7 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh,
spin_unlock(&e->lock);
}
done:
- write_unlock_bh(&d->lock);
+ write_unlock_bh(&d->lock, bh);
return e;
}
EXPORT_SYMBOL(cxgb4_l2t_get);
@@ -536,6 +537,7 @@ static void handle_failed_resolution(struct adapter *adap, struct l2t_entry *e)
*/
void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
{
+ unsigned int bh;
struct l2t_entry *e;
struct sk_buff_head *arpq = NULL;
struct l2t_data *d = adap->l2t;
@@ -544,7 +546,7 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
int ifidx = neigh->dev->ifindex;
int hash = addr_hash(d, addr, addr_len, ifidx);

- read_lock_bh(&d->lock);
+ bh = read_lock_bh(&d->lock, SOFTIRQ_ALL_MASK);
for (e = d->l2tab[hash].first; e; e = e->next)
if (!addreq(e, addr) && e->ifindex == ifidx) {
spin_lock(&e->lock);
@@ -553,7 +555,7 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
spin_unlock(&e->lock);
break;
}
- read_unlock_bh(&d->lock);
+ read_unlock_bh(&d->lock, bh);
return;

found:
@@ -588,11 +590,12 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh)
struct l2t_entry *t4_l2t_alloc_switching(struct adapter *adap, u16 vlan,
u8 port, u8 *eth_addr)
{
+ unsigned int bh;
struct l2t_data *d = adap->l2t;
struct l2t_entry *e;
int ret;

- write_lock_bh(&d->lock);
+ bh = write_lock_bh(&d->lock, SOFTIRQ_ALL_MASK);
e = find_or_alloc_l2e(d, vlan, port, eth_addr);
if (e) {
spin_lock(&e->lock); /* avoid race with t4_l2t_free */
@@ -606,7 +609,7 @@ struct l2t_entry *t4_l2t_alloc_switching(struct adapter *adap, u16 vlan,
if (ret < 0) {
_t4_l2e_free(e);
spin_unlock(&e->lock);
- write_unlock_bh(&d->lock);
+ write_unlock_bh(&d->lock, bh);
return NULL;
}
} else {
@@ -615,7 +618,7 @@ struct l2t_entry *t4_l2t_alloc_switching(struct adapter *adap, u16 vlan,

spin_unlock(&e->lock);
}
- write_unlock_bh(&d->lock);
+ write_unlock_bh(&d->lock, bh);
return e;
}

diff --git a/drivers/net/ethernet/chelsio/cxgb4/smt.c b/drivers/net/ethernet/chelsio/cxgb4/smt.c
index c660e9d..7201434 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/smt.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/smt.c
@@ -210,10 +210,11 @@ static int write_smt_entry(struct adapter *adapter, struct smt_entry *e)
static struct smt_entry *t4_smt_alloc_switching(struct adapter *adap, u16 pfvf,
u8 *smac)
{
+ unsigned int bh;
struct smt_data *s = adap->smt;
struct smt_entry *e;

- write_lock_bh(&s->lock);
+ bh = write_lock_bh(&s->lock, SOFTIRQ_ALL_MASK);
e = find_or_alloc_smte(s, smac);
if (e) {
spin_lock(&e->lock);
@@ -228,7 +229,7 @@ static struct smt_entry *t4_smt_alloc_switching(struct adapter *adap, u16 pfvf,
}
spin_unlock(&e->lock);
}
- write_unlock_bh(&s->lock);
+ write_unlock_bh(&s->lock, bh);
return e;
}

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 48a1f16..bb6b21c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -386,6 +386,7 @@ static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,

static void mlx5e_rep_neigh_update(struct work_struct *work)
{
+ unsigned int bh;
struct mlx5e_neigh_hash_entry *nhe =
container_of(work, struct mlx5e_neigh_hash_entry, neigh_update_work);
struct neighbour *n = nhe->n;
@@ -403,11 +404,11 @@ static void mlx5e_rep_neigh_update(struct work_struct *work)
* We use this lock to avoid inconsistency between the neigh validity
* and it's hw address.
*/
- read_lock_bh(&n->lock);
+ bh = read_lock_bh(&n->lock, SOFTIRQ_ALL_MASK);
memcpy(ha, n->ha, ETH_ALEN);
nud_state = n->nud_state;
dead = n->dead;
- read_unlock_bh(&n->lock);
+ read_unlock_bh(&n->lock, bh);

neigh_connected = (nud_state & NUD_VALID) && !dead;

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 9fed540..ffe8e61 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -2307,6 +2307,7 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
struct net_device *mirred_dev,
struct mlx5e_encap_entry *e)
{
+ unsigned int bh;
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
int ipv4_encap_size = ETH_HLEN + sizeof(struct iphdr) + VXLAN_HLEN;
struct ip_tunnel_key *tun_key = &e->tun_info.key;
@@ -2366,10 +2367,10 @@ static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
if (err)
goto free_encap;

- read_lock_bh(&n->lock);
+ bh = read_lock_bh(&n->lock, SOFTIRQ_ALL_MASK);
nud_state = n->nud_state;
ether_addr_copy(e->h_dest, n->ha);
- read_unlock_bh(&n->lock);
+ read_unlock_bh(&n->lock, bh);

switch (e->tunnel_type) {
case MLX5_HEADER_TYPE_VXLAN:
@@ -2416,6 +2417,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
struct net_device *mirred_dev,
struct mlx5e_encap_entry *e)
{
+ unsigned int bh;
int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
int ipv6_encap_size = ETH_HLEN + sizeof(struct ipv6hdr) + VXLAN_HLEN;
struct ip_tunnel_key *tun_key = &e->tun_info.key;
@@ -2475,10 +2477,10 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
if (err)
goto free_encap;

- read_lock_bh(&n->lock);
+ bh = read_lock_bh(&n->lock, SOFTIRQ_ALL_MASK);
nud_state = n->nud_state;
ether_addr_copy(e->h_dest, n->ha);
- read_unlock_bh(&n->lock);
+ read_unlock_bh(&n->lock, bh);

switch (e->tunnel_type) {
case MLX5_HEADER_TYPE_VXLAN:
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 2ab9cf2..420d0e0 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -2345,6 +2345,7 @@ struct mlxsw_sp_netevent_work {

static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
{
+ unsigned int bh;
struct mlxsw_sp_netevent_work *net_work =
container_of(work, struct mlxsw_sp_netevent_work, work);
struct mlxsw_sp *mlxsw_sp = net_work->mlxsw_sp;
@@ -2358,11 +2359,11 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
* then we are guaranteed to receive another event letting us
* know about it.
*/
- read_lock_bh(&n->lock);
+ bh = read_lock_bh(&n->lock, SOFTIRQ_ALL_MASK);
memcpy(ha, n->ha, ETH_ALEN);
nud_state = n->nud_state;
dead = n->dead;
- read_unlock_bh(&n->lock);
+ read_unlock_bh(&n->lock, bh);

rtnl_lock();
mlxsw_sp_span_respin(mlxsw_sp);
@@ -3379,6 +3380,7 @@ static void mlxsw_sp_nexthop_rif_fini(struct mlxsw_sp_nexthop *nh)
static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_nexthop *nh)
{
+ unsigned int bh;
struct mlxsw_sp_neigh_entry *neigh_entry;
struct neighbour *n;
u8 nud_state, dead;
@@ -3418,10 +3420,10 @@ static int mlxsw_sp_nexthop_neigh_init(struct mlxsw_sp *mlxsw_sp,

nh->neigh_entry = neigh_entry;
list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list);
- read_lock_bh(&n->lock);
+ bh = read_lock_bh(&n->lock, SOFTIRQ_ALL_MASK);
nud_state = n->nud_state;
dead = n->dead;
- read_unlock_bh(&n->lock);
+ read_unlock_bh(&n->lock, bh);
__mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID && !dead));

return 0;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index d965fd2..40517d2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -110,6 +110,7 @@ static int mlxsw_sp_span_dmac(struct neigh_table *tbl,
struct net_device *dev,
unsigned char dmac[ETH_ALEN])
{
+ unsigned int bh;
struct neighbour *neigh = neigh_lookup(tbl, pkey, dev);
int err = 0;

@@ -121,12 +122,12 @@ static int mlxsw_sp_span_dmac(struct neigh_table *tbl,

neigh_event_send(neigh, NULL);

- read_lock_bh(&neigh->lock);
+ bh = read_lock_bh(&neigh->lock, SOFTIRQ_ALL_MASK);
if ((neigh->nud_state & NUD_VALID) && !neigh->dead)
memcpy(dmac, neigh->ha, ETH_ALEN);
else
err = -ENOENT;
- read_unlock_bh(&neigh->lock);
+ read_unlock_bh(&neigh->lock, bh);

neigh_release(neigh);
return err;
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 8317571..0bf7009 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -661,12 +661,13 @@ static int sixpack_open(struct tty_struct *tty)
*/
static void sixpack_close(struct tty_struct *tty)
{
+ unsigned int bh;
struct sixpack *sp;

- write_lock_bh(&disc_data_lock);
+ bh = write_lock_bh(&disc_data_lock, SOFTIRQ_ALL_MASK);
sp = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_bh(&disc_data_lock);
+ write_unlock_bh(&disc_data_lock, bh);
if (!sp)
return;

diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index ff57063..dce4a3f 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -786,12 +786,13 @@ static int mkiss_open(struct tty_struct *tty)

static void mkiss_close(struct tty_struct *tty)
{
+ unsigned int bh;
struct mkiss *ax;

- write_lock_bh(&disc_data_lock);
+ bh = write_lock_bh(&disc_data_lock, SOFTIRQ_ALL_MASK);
ax = tty->disc_data;
tty->disc_data = NULL;
- write_unlock_bh(&disc_data_lock);
+ write_unlock_bh(&disc_data_lock, bh);

if (!ax)
return;
diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c
index 3b0588d..72d7369 100644
--- a/drivers/net/ieee802154/fakelb.c
+++ b/drivers/net/ieee802154/fakelb.c
@@ -57,20 +57,22 @@ static int fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)

static int fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{
+ unsigned int bh;
struct fakelb_phy *phy = hw->priv;

- write_lock_bh(&fakelb_ifup_phys_lock);
+ bh = write_lock_bh(&fakelb_ifup_phys_lock, SOFTIRQ_ALL_MASK);
phy->page = page;
phy->channel = channel;
- write_unlock_bh(&fakelb_ifup_phys_lock);
+ write_unlock_bh(&fakelb_ifup_phys_lock, bh);
return 0;
}

static int fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
{
+ unsigned int bh;
struct fakelb_phy *current_phy = hw->priv, *phy;

- read_lock_bh(&fakelb_ifup_phys_lock);
+ bh = read_lock_bh(&fakelb_ifup_phys_lock, SOFTIRQ_ALL_MASK);
WARN_ON(current_phy->suspended);
list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) {
if (current_phy == phy)
@@ -84,7 +86,7 @@ static int fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
ieee802154_rx_irqsafe(phy->hw, newskb, 0xcc);
}
}
- read_unlock_bh(&fakelb_ifup_phys_lock);
+ read_unlock_bh(&fakelb_ifup_phys_lock, bh);

ieee802154_xmit_complete(hw, skb, false);
return 0;
@@ -92,24 +94,26 @@ static int fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)

static int fakelb_hw_start(struct ieee802154_hw *hw)
{
+ unsigned int bh;
struct fakelb_phy *phy = hw->priv;

- write_lock_bh(&fakelb_ifup_phys_lock);
+ bh = write_lock_bh(&fakelb_ifup_phys_lock, SOFTIRQ_ALL_MASK);
phy->suspended = false;
list_add(&phy->list_ifup, &fakelb_ifup_phys);
- write_unlock_bh(&fakelb_ifup_phys_lock);
+ write_unlock_bh(&fakelb_ifup_phys_lock, bh);

return 0;
}

static void fakelb_hw_stop(struct ieee802154_hw *hw)
{
+ unsigned int bh;
struct fakelb_phy *phy = hw->priv;

- write_lock_bh(&fakelb_ifup_phys_lock);
+ bh = write_lock_bh(&fakelb_ifup_phys_lock, SOFTIRQ_ALL_MASK);
phy->suspended = true;
list_del(&phy->list_ifup);
- write_unlock_bh(&fakelb_ifup_phys_lock);
+ write_unlock_bh(&fakelb_ifup_phys_lock, bh);
}

static int
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index c6cda50..23bc409 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1935,7 +1935,8 @@ static void __ppp_channel_push(struct channel *pch)

static void ppp_channel_push(struct channel *pch)
{
- read_lock_bh(&pch->upl);
+ unsigned int bh;
+ bh = read_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
if (pch->ppp) {
(*this_cpu_ptr(pch->ppp->xmit_recursion))++;
__ppp_channel_push(pch);
@@ -1943,7 +1944,7 @@ static void ppp_channel_push(struct channel *pch)
} else {
__ppp_channel_push(pch);
}
- read_unlock_bh(&pch->upl);
+ read_unlock_bh(&pch->upl, bh);
}

/*
@@ -1970,6 +1971,7 @@ ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
void
ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
{
+ unsigned int bh;
struct channel *pch = chan->ppp;
int proto;

@@ -1978,7 +1980,7 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
return;
}

- read_lock_bh(&pch->upl);
+ bh = read_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
if (!pskb_may_pull(skb, 2)) {
kfree_skb(skb);
if (pch->ppp) {
@@ -2002,20 +2004,21 @@ ppp_input(struct ppp_channel *chan, struct sk_buff *skb)
}

done:
- read_unlock_bh(&pch->upl);
+ read_unlock_bh(&pch->upl, bh);
}

/* Put a 0-length skb in the receive queue as an error indication */
void
ppp_input_error(struct ppp_channel *chan, int code)
{
+ unsigned int bh;
struct channel *pch = chan->ppp;
struct sk_buff *skb;

if (!pch)
return;

- read_lock_bh(&pch->upl);
+ bh = read_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
if (pch->ppp) {
skb = alloc_skb(0, GFP_ATOMIC);
if (skb) {
@@ -2024,7 +2027,7 @@ ppp_input_error(struct ppp_channel *chan, int code)
ppp_do_recv(pch->ppp, skb, pch);
}
}
- read_unlock_bh(&pch->upl);
+ read_unlock_bh(&pch->upl, bh);
}

/*
@@ -2606,14 +2609,15 @@ int ppp_channel_index(struct ppp_channel *chan)
*/
int ppp_unit_number(struct ppp_channel *chan)
{
+ unsigned int bh;
struct channel *pch = chan->ppp;
int unit = -1;

if (pch) {
- read_lock_bh(&pch->upl);
+ bh = read_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
if (pch->ppp)
unit = pch->ppp->file.index;
- read_unlock_bh(&pch->upl);
+ read_unlock_bh(&pch->upl, bh);
}
return unit;
}
@@ -2623,14 +2627,15 @@ int ppp_unit_number(struct ppp_channel *chan)
*/
char *ppp_dev_name(struct ppp_channel *chan)
{
+ unsigned int bh;
struct channel *pch = chan->ppp;
char *name = NULL;

if (pch) {
- read_lock_bh(&pch->upl);
+ bh = read_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
if (pch->ppp && pch->ppp->dev)
name = pch->ppp->dev->name;
- read_unlock_bh(&pch->upl);
+ read_unlock_bh(&pch->upl, bh);
}
return name;
}
@@ -3134,6 +3139,7 @@ static int
ppp_connect_channel(struct channel *pch, int unit)
{
unsigned int bh;
+ unsigned int bh;
struct ppp *ppp;
struct ppp_net *pn;
int ret = -ENXIO;
@@ -3145,7 +3151,7 @@ ppp_connect_channel(struct channel *pch, int unit)
ppp = ppp_find_unit(pn, unit);
if (!ppp)
goto out;
- write_lock_bh(&pch->upl);
+ bh = write_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
ret = -EINVAL;
if (pch->ppp)
goto outl;
@@ -3173,7 +3179,7 @@ ppp_connect_channel(struct channel *pch, int unit)
ret = 0;

outl:
- write_unlock_bh(&pch->upl);
+ write_unlock_bh(&pch->upl, bh);
out:
mutex_unlock(&pn->all_ppp_mutex);
return ret;
@@ -3185,13 +3191,14 @@ ppp_connect_channel(struct channel *pch, int unit)
static int
ppp_disconnect_channel(struct channel *pch)
{
+ unsigned int bh;
struct ppp *ppp;
int err = -EINVAL;

- write_lock_bh(&pch->upl);
+ bh = write_lock_bh(&pch->upl, SOFTIRQ_ALL_MASK);
ppp = pch->ppp;
pch->ppp = NULL;
- write_unlock_bh(&pch->upl);
+ write_unlock_bh(&pch->upl, bh);
if (ppp) {
/* remove it from the ppp unit's list */
ppp_lock(ppp);
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 62dc564..68bf348 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -230,13 +230,14 @@ static void __delete_item(struct pppoe_net *pn, __be16 sid,
static inline struct pppox_sock *get_item(struct pppoe_net *pn, __be16 sid,
unsigned char *addr, int ifindex)
{
+ unsigned int bh;
struct pppox_sock *po;

- read_lock_bh(&pn->hash_lock);
+ bh = read_lock_bh(&pn->hash_lock, SOFTIRQ_ALL_MASK);
po = __get_item(pn, sid, addr, ifindex);
if (po)
sock_hold(sk_pppox(po));
- read_unlock_bh(&pn->hash_lock);
+ read_unlock_bh(&pn->hash_lock, bh);

return po;
}
@@ -265,9 +266,10 @@ static inline struct pppox_sock *get_item_by_addr(struct net *net,
static inline void delete_item(struct pppoe_net *pn, __be16 sid,
char *addr, int ifindex)
{
- write_lock_bh(&pn->hash_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&pn->hash_lock, SOFTIRQ_ALL_MASK);
__delete_item(pn, sid, addr, ifindex);
- write_unlock_bh(&pn->hash_lock);
+ write_unlock_bh(&pn->hash_lock, bh);
}

/***************************************************************************
@@ -279,11 +281,12 @@ static inline void delete_item(struct pppoe_net *pn, __be16 sid,

static void pppoe_flush_dev(struct net_device *dev)
{
+ unsigned int bh;
struct pppoe_net *pn;
int i;

pn = pppoe_pernet(dev_net(dev));
- write_lock_bh(&pn->hash_lock);
+ bh = write_lock_bh(&pn->hash_lock, SOFTIRQ_ALL_MASK);
for (i = 0; i < PPPOE_HASH_SIZE; i++) {
struct pppox_sock *po = pn->hash_table[i];
struct sock *sk;
@@ -327,11 +330,11 @@ static void pppoe_flush_dev(struct net_device *dev)
*/

BUG_ON(pppoe_pernet(dev_net(dev)) == NULL);
- write_lock_bh(&pn->hash_lock);
+ write_lock_bh(&pn->hash_lock, SOFTIRQ_ALL_MASK);
po = pn->hash_table[i];
}
}
- write_unlock_bh(&pn->hash_lock);
+ write_unlock_bh(&pn->hash_lock, bh);
}

static int pppoe_device_event(struct notifier_block *this,
@@ -612,6 +615,7 @@ static int pppoe_release(struct socket *sock)
static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
int sockaddr_len, int flags)
{
+ unsigned int bh;
struct sock *sk = sock->sk;
struct sockaddr_pppox *sp = (struct sockaddr_pppox *)uservaddr;
struct pppox_sock *po = pppox_sk(sk);
@@ -684,9 +688,9 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
&sp->sa_addr.pppoe,
sizeof(struct pppoe_addr));

- write_lock_bh(&pn->hash_lock);
+ bh = write_lock_bh(&pn->hash_lock, SOFTIRQ_ALL_MASK);
error = __set_item(pn, po);
- write_unlock_bh(&pn->hash_lock);
+ write_unlock_bh(&pn->hash_lock, bh);
if (error < 0)
goto err_put;

@@ -1054,7 +1058,7 @@ static void *pppoe_seq_start(struct seq_file *seq, loff_t *pos)
struct pppoe_net *pn = pppoe_pernet(seq_file_net(seq));
loff_t l = *pos;

- read_lock_bh(&pn->hash_lock);
+ read_lock_bh(&pn->hash_lock, SOFTIRQ_ALL_MASK);
return l ? pppoe_get_idx(pn, --l) : SEQ_START_TOKEN;
}

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 79bdae9..ea8c31f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -99,13 +99,14 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct inet6_dev *idev)
{
+ unsigned int bh;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct inet6_ifaddr *ifa;
int idx = 0;

memset(mvmvif->tentative_addrs, 0, sizeof(mvmvif->tentative_addrs));

- read_lock_bh(&idev->lock);
+ bh = read_lock_bh(&idev->lock, SOFTIRQ_ALL_MASK);
list_for_each_entry(ifa, &idev->addr_list, if_list) {
mvmvif->target_ipv6_addrs[idx] = ifa->addr;
if (ifa->flags & IFA_F_TENTATIVE)
@@ -114,7 +115,7 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)
break;
}
- read_unlock_bh(&idev->lock);
+ read_unlock_bh(&idev->lock, bh);

mvmvif->num_target_ipv6_addrs = idx;
}
diff --git a/drivers/net/wireless/intersil/hostap/hostap_80211_rx.c b/drivers/net/wireless/intersil/hostap/hostap_80211_rx.c
index 61be822..d6cf897 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_80211_rx.c
@@ -532,10 +532,11 @@ hostap_rx_frame_mgmt(local_info_t *local, struct sk_buff *skb,
static struct net_device *prism2_rx_get_wds(local_info_t *local,
u8 *addr)
{
+ unsigned int bh;
struct hostap_interface *iface = NULL;
struct list_head *ptr;

- read_lock_bh(&local->iface_lock);
+ bh = read_lock_bh(&local->iface_lock, SOFTIRQ_ALL_MASK);
list_for_each(ptr, &local->hostap_interfaces) {
iface = list_entry(ptr, struct hostap_interface, list);
if (iface->type == HOSTAP_INTERFACE_WDS &&
@@ -543,7 +544,7 @@ static struct net_device *prism2_rx_get_wds(local_info_t *local,
break;
iface = NULL;
}
- read_unlock_bh(&local->iface_lock);
+ read_unlock_bh(&local->iface_lock, bh);

return iface ? iface->dev : NULL;
}
diff --git a/drivers/net/wireless/intersil/hostap/hostap_main.c b/drivers/net/wireless/intersil/hostap/hostap_main.c
index 012930d..004318f 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
@@ -142,12 +142,13 @@ static inline int prism2_wds_special_addr(u8 *addr)
int prism2_wds_add(local_info_t *local, u8 *remote_addr,
int rtnl_locked)
{
+ unsigned int bh;
struct net_device *dev;
struct list_head *ptr;
struct hostap_interface *iface, *empty, *match;

empty = match = NULL;
- read_lock_bh(&local->iface_lock);
+ bh = read_lock_bh(&local->iface_lock, SOFTIRQ_ALL_MASK);
list_for_each(ptr, &local->hostap_interfaces) {
iface = list_entry(ptr, struct hostap_interface, list);
if (iface->type != HOSTAP_INTERFACE_WDS)
@@ -163,12 +164,12 @@ int prism2_wds_add(local_info_t *local, u8 *remote_addr,
if (!match && empty && !prism2_wds_special_addr(remote_addr)) {
/* take pre-allocated entry into use */
memcpy(empty->u.wds.remote_addr, remote_addr, ETH_ALEN);
- read_unlock_bh(&local->iface_lock);
+ read_unlock_bh(&local->iface_lock, bh);
printk(KERN_DEBUG "%s: using pre-allocated WDS netdevice %s\n",
local->dev->name, empty->dev->name);
return 0;
}
- read_unlock_bh(&local->iface_lock);
+ read_unlock_bh(&local->iface_lock, bh);

if (!prism2_wds_special_addr(remote_addr)) {
if (match)
@@ -702,6 +703,7 @@ static int prism2_open(struct net_device *dev)

static int prism2_set_mac_address(struct net_device *dev, void *p)
{
+ unsigned int bh;
struct hostap_interface *iface;
local_info_t *local;
struct list_head *ptr;
@@ -714,13 +716,13 @@ static int prism2_set_mac_address(struct net_device *dev, void *p)
ETH_ALEN) < 0 || local->func->reset_port(dev))
return -EINVAL;

- read_lock_bh(&local->iface_lock);
+ bh = read_lock_bh(&local->iface_lock, SOFTIRQ_ALL_MASK);
list_for_each(ptr, &local->hostap_interfaces) {
iface = list_entry(ptr, struct hostap_interface, list);
memcpy(iface->dev->dev_addr, addr->sa_data, ETH_ALEN);
}
memcpy(local->dev->dev_addr, addr->sa_data, ETH_ALEN);
- read_unlock_bh(&local->iface_lock);
+ read_unlock_bh(&local->iface_lock, bh);

return 0;
}
diff --git a/drivers/net/wireless/intersil/hostap/hostap_proc.c b/drivers/net/wireless/intersil/hostap/hostap_proc.c
index 56ae726..f3042bb 100644
--- a/drivers/net/wireless/intersil/hostap/hostap_proc.c
+++ b/drivers/net/wireless/intersil/hostap/hostap_proc.c
@@ -98,7 +98,7 @@ static int prism2_wds_proc_show(struct seq_file *m, void *v)
static void *prism2_wds_proc_start(struct seq_file *m, loff_t *_pos)
{
local_info_t *local = PDE_DATA(file_inode(m->file));
- read_lock_bh(&local->iface_lock);
+ read_lock_bh(&local->iface_lock, SOFTIRQ_ALL_MASK);
return seq_list_start(&local->hostap_interfaces, *_pos);
}

diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 5ce2424..1a48261 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -543,6 +543,7 @@ static void netiucv_callback_connack(struct iucv_path *path, u8 ipuser[16])
static int netiucv_callback_connreq(struct iucv_path *path, u8 *ipvmid,
u8 *ipuser)
{
+ unsigned int bh;
struct iucv_connection *conn = path->private;
struct iucv_event ev;
static char tmp_user[9];
@@ -553,7 +554,7 @@ static int netiucv_callback_connreq(struct iucv_path *path, u8 *ipvmid,
memcpy(tmp_user, netiucv_printname(ipvmid, 8), 8);
memcpy(tmp_udat, ipuser, 16);
EBCASC(tmp_udat, 16);
- read_lock_bh(&iucv_connection_rwlock);
+ bh = read_lock_bh(&iucv_connection_rwlock, SOFTIRQ_ALL_MASK);
list_for_each_entry(conn, &iucv_connection_list, list) {
if (strncmp(ipvmid, conn->userid, 8) ||
strncmp(ipuser, conn->userdata, 16))
@@ -567,7 +568,7 @@ static int netiucv_callback_connreq(struct iucv_path *path, u8 *ipvmid,
}
IUCV_DBF_TEXT_(setup, 2, "Connection requested for %s.%s\n",
tmp_user, netiucv_printname(tmp_udat, 16));
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);
return rc;
}

@@ -1476,6 +1477,7 @@ static int netiucv_check_user(const char *buf, size_t count, char *username,
static ssize_t user_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
+ unsigned int bh;
struct netiucv_priv *priv = dev_get_drvdata(dev);
struct net_device *ndev = priv->conn->netdev;
char username[9];
@@ -1494,17 +1496,17 @@ static ssize_t user_write(struct device *dev, struct device_attribute *attr,
IUCV_DBF_TEXT(setup, 2, "user_write: device active\n");
return -EPERM;
}
- read_lock_bh(&iucv_connection_rwlock);
+ bh = read_lock_bh(&iucv_connection_rwlock, SOFTIRQ_ALL_MASK);
list_for_each_entry(cp, &iucv_connection_list, list) {
if (!strncmp(username, cp->userid, 9) &&
!strncmp(userdata, cp->userdata, 17) && cp->netdev != ndev) {
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);
IUCV_DBF_TEXT_(setup, 2, "user_write: Connection to %s "
"already exists\n", netiucv_printuser(cp));
return -EEXIST;
}
}
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);
memcpy(priv->conn->userid, username, 9);
memcpy(priv->conn->userdata, userdata, 17);
return count;
@@ -1845,6 +1847,7 @@ static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
char *username,
char *userdata)
{
+ unsigned int bh;
struct iucv_connection *conn;

conn = kzalloc(sizeof(*conn), GFP_KERNEL);
@@ -1879,9 +1882,9 @@ static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
fsm_newstate(conn->fsm, CONN_STATE_STOPPED);
}

- write_lock_bh(&iucv_connection_rwlock);
+ bh = write_lock_bh(&iucv_connection_rwlock, SOFTIRQ_ALL_MASK);
list_add_tail(&conn->list, &iucv_connection_list);
- write_unlock_bh(&iucv_connection_rwlock);
+ write_unlock_bh(&iucv_connection_rwlock, bh);
return conn;

out_tx:
@@ -1900,11 +1903,12 @@ static struct iucv_connection *netiucv_new_connection(struct net_device *dev,
*/
static void netiucv_remove_connection(struct iucv_connection *conn)
{
+ unsigned int bh;

IUCV_DBF_TEXT(trace, 3, __func__);
- write_lock_bh(&iucv_connection_rwlock);
+ bh = write_lock_bh(&iucv_connection_rwlock, SOFTIRQ_ALL_MASK);
list_del_init(&conn->list);
- write_unlock_bh(&iucv_connection_rwlock);
+ write_unlock_bh(&iucv_connection_rwlock, bh);
fsm_deltimer(&conn->timer);
netiucv_purge_skb_queue(&conn->collect_queue);
if (conn->path) {
@@ -2007,6 +2011,7 @@ static struct net_device *netiucv_init_netdevice(char *username, char *userdata)
static ssize_t connection_store(struct device_driver *drv, const char *buf,
size_t count)
{
+ unsigned int bh;
char username[9];
char userdata[17];
int rc;
@@ -2019,17 +2024,17 @@ static ssize_t connection_store(struct device_driver *drv, const char *buf,
if (rc)
return rc;

- read_lock_bh(&iucv_connection_rwlock);
+ bh = read_lock_bh(&iucv_connection_rwlock, SOFTIRQ_ALL_MASK);
list_for_each_entry(cp, &iucv_connection_list, list) {
if (!strncmp(username, cp->userid, 9) &&
!strncmp(userdata, cp->userdata, 17)) {
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);
IUCV_DBF_TEXT_(setup, 2, "conn_write: Connection to %s "
"already exists\n", netiucv_printuser(cp));
return -EEXIST;
}
}
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);

dev = netiucv_init_netdevice(username, userdata);
if (!dev) {
@@ -2071,6 +2076,7 @@ static DRIVER_ATTR_WO(connection);
static ssize_t remove_store(struct device_driver *drv, const char *buf,
size_t count)
{
+ unsigned int bh;
struct iucv_connection *cp;
struct net_device *ndev;
struct netiucv_priv *priv;
@@ -2092,14 +2098,14 @@ static ssize_t remove_store(struct device_driver *drv, const char *buf,
}
name[i] = '\0';

- read_lock_bh(&iucv_connection_rwlock);
+ bh = read_lock_bh(&iucv_connection_rwlock, SOFTIRQ_ALL_MASK);
list_for_each_entry(cp, &iucv_connection_list, list) {
ndev = cp->netdev;
priv = netdev_priv(ndev);
dev = priv->dev;
if (strncmp(name, ndev->name, count))
continue;
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);
if (ndev->flags & (IFF_UP | IFF_RUNNING)) {
dev_warn(dev, "The IUCV device is connected"
" to %s and cannot be removed\n",
@@ -2111,7 +2117,7 @@ static ssize_t remove_store(struct device_driver *drv, const char *buf,
netiucv_unregister_device(dev);
return count;
}
- read_unlock_bh(&iucv_connection_rwlock);
+ read_unlock_bh(&iucv_connection_rwlock, bh);
IUCV_DBF_TEXT(data, 2, "remove_write: unknown device\n");
return -EINVAL;
}
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 16df663..085cbd9 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1229,6 +1229,7 @@ static void qeth_l3_add_mc6_to_hash(struct qeth_card *card,
/* called with rcu_read_lock */
static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
{
+ unsigned int bh;
struct inet6_dev *in_dev;
u16 vid;

@@ -1248,15 +1249,16 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card)
in_dev = in6_dev_get(netdev);
if (!in_dev)
continue;
- read_lock_bh(&in_dev->lock);
+ bh = read_lock_bh(&in_dev->lock, SOFTIRQ_ALL_MASK);
qeth_l3_add_mc6_to_hash(card, in_dev);
- read_unlock_bh(&in_dev->lock);
+ read_unlock_bh(&in_dev->lock, bh);
in6_dev_put(in_dev);
}
}

static void qeth_l3_add_multicast_ipv6(struct qeth_card *card)
{
+ unsigned int bh;
struct inet6_dev *in6_dev;

QETH_CARD_TEXT(card, 4, "chkmcv6");
@@ -1268,10 +1270,10 @@ static void qeth_l3_add_multicast_ipv6(struct qeth_card *card)
return;

rcu_read_lock();
- read_lock_bh(&in6_dev->lock);
+ bh = read_lock_bh(&in6_dev->lock, SOFTIRQ_ALL_MASK);
qeth_l3_add_mc6_to_hash(card, in6_dev);
qeth_l3_add_vlan_mc6(card);
- read_unlock_bh(&in6_dev->lock);
+ read_unlock_bh(&in6_dev->lock, bh);
rcu_read_unlock();
in6_dev_put(in6_dev);
}
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index cda021f..12817ce 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -606,9 +606,10 @@ void bnx2i_drop_session(struct iscsi_cls_session *cls_session)
static int bnx2i_ep_destroy_list_add(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- write_lock_bh(&hba->ep_rdwr_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_add_tail(&ep->link, &hba->ep_destroy_list);
- write_unlock_bh(&hba->ep_rdwr_lock);
+ write_unlock_bh(&hba->ep_rdwr_lock, bh);
return 0;
}

@@ -623,9 +624,10 @@ static int bnx2i_ep_destroy_list_add(struct bnx2i_hba *hba,
static int bnx2i_ep_destroy_list_del(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- write_lock_bh(&hba->ep_rdwr_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_del_init(&ep->link);
- write_unlock_bh(&hba->ep_rdwr_lock);
+ write_unlock_bh(&hba->ep_rdwr_lock, bh);

return 0;
}
@@ -640,9 +642,10 @@ static int bnx2i_ep_destroy_list_del(struct bnx2i_hba *hba,
static int bnx2i_ep_ofld_list_add(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- write_lock_bh(&hba->ep_rdwr_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_add_tail(&ep->link, &hba->ep_ofld_list);
- write_unlock_bh(&hba->ep_rdwr_lock);
+ write_unlock_bh(&hba->ep_rdwr_lock, bh);
return 0;
}

@@ -656,9 +659,10 @@ static int bnx2i_ep_ofld_list_add(struct bnx2i_hba *hba,
static int bnx2i_ep_ofld_list_del(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- write_lock_bh(&hba->ep_rdwr_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_del_init(&ep->link);
- write_unlock_bh(&hba->ep_rdwr_lock);
+ write_unlock_bh(&hba->ep_rdwr_lock, bh);
return 0;
}

@@ -673,11 +677,12 @@ static int bnx2i_ep_ofld_list_del(struct bnx2i_hba *hba,
struct bnx2i_endpoint *
bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid)
{
+ unsigned int bh;
struct list_head *list;
struct list_head *tmp;
struct bnx2i_endpoint *ep = NULL;

- read_lock_bh(&hba->ep_rdwr_lock);
+ bh = read_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_for_each_safe(list, tmp, &hba->ep_ofld_list) {
ep = (struct bnx2i_endpoint *)list;

@@ -685,7 +690,7 @@ bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid)
break;
ep = NULL;
}
- read_unlock_bh(&hba->ep_rdwr_lock);
+ read_unlock_bh(&hba->ep_rdwr_lock, bh);

if (!ep)
printk(KERN_ERR "l5 cid %d not found\n", iscsi_cid);
@@ -701,11 +706,12 @@ bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid)
struct bnx2i_endpoint *
bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid)
{
+ unsigned int bh;
struct list_head *list;
struct list_head *tmp;
struct bnx2i_endpoint *ep = NULL;

- read_lock_bh(&hba->ep_rdwr_lock);
+ bh = read_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_for_each_safe(list, tmp, &hba->ep_destroy_list) {
ep = (struct bnx2i_endpoint *)list;

@@ -713,7 +719,7 @@ bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid)
break;
ep = NULL;
}
- read_unlock_bh(&hba->ep_rdwr_lock);
+ read_unlock_bh(&hba->ep_rdwr_lock, bh);

if (!ep)
printk(KERN_ERR "l5 cid %d not found\n", iscsi_cid);
@@ -731,9 +737,10 @@ bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid)
static void bnx2i_ep_active_list_add(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- write_lock_bh(&hba->ep_rdwr_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_add_tail(&ep->link, &hba->ep_active_list);
- write_unlock_bh(&hba->ep_rdwr_lock);
+ write_unlock_bh(&hba->ep_rdwr_lock, bh);
}


@@ -747,9 +754,10 @@ static void bnx2i_ep_active_list_add(struct bnx2i_hba *hba,
static void bnx2i_ep_active_list_del(struct bnx2i_hba *hba,
struct bnx2i_endpoint *ep)
{
- write_lock_bh(&hba->ep_rdwr_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
list_del_init(&ep->link);
- write_unlock_bh(&hba->ep_rdwr_lock);
+ write_unlock_bh(&hba->ep_rdwr_lock, bh);
}


@@ -1558,6 +1566,7 @@ static int bnx2i_ep_get_param(struct iscsi_endpoint *ep,
static int bnx2i_host_get_param(struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf)
{
+ unsigned int bh;
struct bnx2i_hba *hba = iscsi_host_priv(shost);
int len = 0;

@@ -1571,7 +1580,7 @@ static int bnx2i_host_get_param(struct Scsi_Host *shost,
case ISCSI_HOST_PARAM_IPADDRESS: {
struct list_head *active_list = &hba->ep_active_list;

- read_lock_bh(&hba->ep_rdwr_lock);
+ bh = read_lock_bh(&hba->ep_rdwr_lock, SOFTIRQ_ALL_MASK);
if (!list_empty(&hba->ep_active_list)) {
struct bnx2i_endpoint *bnx2i_ep;
struct cnic_sock *csk;
@@ -1585,7 +1594,7 @@ static int bnx2i_host_get_param(struct Scsi_Host *shost,
else
len = sprintf(buf, "%pI4\n", csk->src_ip);
}
- read_unlock_bh(&hba->ep_rdwr_lock);
+ read_unlock_bh(&hba->ep_rdwr_lock, bh);
break;
}
default:
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index 6f59276..2885e60 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -836,16 +836,17 @@ EXPORT_SYMBOL_GPL(cxgbi_sock_established);

static void cxgbi_inform_iscsi_conn_closing(struct cxgbi_sock *csk)
{
+ unsigned int bh;
log_debug(1 << CXGBI_DBG_SOCK,
"csk 0x%p, state %u, flags 0x%lx, conn 0x%p.\n",
csk, csk->state, csk->flags, csk->user_data);

if (csk->state != CTP_ESTABLISHED) {
- read_lock_bh(&csk->callback_lock);
+ bh = read_lock_bh(&csk->callback_lock, SOFTIRQ_ALL_MASK);
if (csk->user_data)
iscsi_conn_failure(csk->user_data,
ISCSI_ERR_TCP_CONN_CLOSE);
- read_unlock_bh(&csk->callback_lock);
+ read_unlock_bh(&csk->callback_lock, bh);
}
}

@@ -2377,6 +2378,7 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
struct iscsi_cls_conn *cls_conn,
u64 transport_eph, int is_leading)
{
+ unsigned int bh;
struct iscsi_conn *conn = cls_conn->dd_data;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct cxgbi_conn *cconn = tcp_conn->dd_data;
@@ -2407,12 +2409,12 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
/* calculate the tag idx bits needed for this conn based on cmds_max */
cconn->task_idx_bits = (__ilog2_u32(conn->session->cmds_max - 1)) + 1;

- write_lock_bh(&csk->callback_lock);
+ bh = write_lock_bh(&csk->callback_lock, SOFTIRQ_ALL_MASK);
csk->user_data = conn;
cconn->chba = cep->chba;
cconn->cep = cep;
cep->cconn = cconn;
- write_unlock_bh(&csk->callback_lock);
+ write_unlock_bh(&csk->callback_lock, bh);

cxgbi_conn_max_xmit_dlength(conn);
cxgbi_conn_max_recv_dlength(conn);
@@ -2664,6 +2666,7 @@ EXPORT_SYMBOL_GPL(cxgbi_ep_poll);

void cxgbi_ep_disconnect(struct iscsi_endpoint *ep)
{
+ unsigned int bh;
struct cxgbi_endpoint *cep = ep->dd_data;
struct cxgbi_conn *cconn = cep->cconn;
struct cxgbi_sock *csk = cep->csk;
@@ -2674,10 +2677,10 @@ void cxgbi_ep_disconnect(struct iscsi_endpoint *ep)

if (cconn && cconn->iconn) {
iscsi_suspend_tx(cconn->iconn);
- write_lock_bh(&csk->callback_lock);
+ bh = write_lock_bh(&csk->callback_lock, SOFTIRQ_ALL_MASK);
cep->csk->user_data = NULL;
cconn->cep = NULL;
- write_unlock_bh(&csk->callback_lock);
+ write_unlock_bh(&csk->callback_lock, bh);
}
iscsi_destroy_endpoint(ep);

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 44a6a66..5d26296 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -129,14 +129,15 @@ static inline int iscsi_sw_sk_state_check(struct sock *sk)

static void iscsi_sw_tcp_data_ready(struct sock *sk)
{
+ unsigned int bh;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
read_descriptor_t rd_desc;

- read_lock_bh(&sk->sk_callback_lock);
+ bh = read_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
conn = sk->sk_user_data;
if (!conn) {
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);
return;
}
tcp_conn = conn->dd_data;
@@ -156,20 +157,21 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)
/* If we had to (atomically) map a highmem page,
* unmap it now. */
iscsi_tcp_segment_unmap(&tcp_conn->in.segment);
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);
}

static void iscsi_sw_tcp_state_change(struct sock *sk)
{
+ unsigned int bh;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
struct iscsi_conn *conn;
void (*old_state_change)(struct sock *);

- read_lock_bh(&sk->sk_callback_lock);
+ bh = read_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
conn = sk->sk_user_data;
if (!conn) {
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);
return;
}

@@ -179,7 +181,7 @@ static void iscsi_sw_tcp_state_change(struct sock *sk)
tcp_sw_conn = tcp_conn->dd_data;
old_state_change = tcp_sw_conn->old_state_change;

- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);

old_state_change(sk);
}
@@ -190,22 +192,23 @@ static void iscsi_sw_tcp_state_change(struct sock *sk)
**/
static void iscsi_sw_tcp_write_space(struct sock *sk)
{
+ unsigned int bh;
struct iscsi_conn *conn;
struct iscsi_tcp_conn *tcp_conn;
struct iscsi_sw_tcp_conn *tcp_sw_conn;
void (*old_write_space)(struct sock *);

- read_lock_bh(&sk->sk_callback_lock);
+ bh = read_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
conn = sk->sk_user_data;
if (!conn) {
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);
return;
}

tcp_conn = conn->dd_data;
tcp_sw_conn = tcp_conn->dd_data;
old_write_space = tcp_sw_conn->old_write_space;
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);

old_write_space(sk);

@@ -215,12 +218,13 @@ static void iscsi_sw_tcp_write_space(struct sock *sk)

static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
{
+ unsigned int bh;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
struct sock *sk = tcp_sw_conn->sock->sk;

/* assign new callbacks */
- write_lock_bh(&sk->sk_callback_lock);
+ bh = write_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sk->sk_user_data = conn;
tcp_sw_conn->old_data_ready = sk->sk_data_ready;
tcp_sw_conn->old_state_change = sk->sk_state_change;
@@ -228,24 +232,25 @@ static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
sk->sk_data_ready = iscsi_sw_tcp_data_ready;
sk->sk_state_change = iscsi_sw_tcp_state_change;
sk->sk_write_space = iscsi_sw_tcp_write_space;
- write_unlock_bh(&sk->sk_callback_lock);
+ write_unlock_bh(&sk->sk_callback_lock, bh);
}

static void
iscsi_sw_tcp_conn_restore_callbacks(struct iscsi_conn *conn)
{
+ unsigned int bh;
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
struct sock *sk = tcp_sw_conn->sock->sk;

/* restore socket callbacks, see also: iscsi_conn_set_callbacks() */
- write_lock_bh(&sk->sk_callback_lock);
+ bh = write_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sk->sk_user_data = NULL;
sk->sk_data_ready = tcp_sw_conn->old_data_ready;
sk->sk_state_change = tcp_sw_conn->old_state_change;
sk->sk_write_space = tcp_sw_conn->old_write_space;
sk->sk_no_check_tx = 0;
- write_unlock_bh(&sk->sk_callback_lock);
+ write_unlock_bh(&sk->sk_callback_lock, bh);
}

/**
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index bc05c69..a812d61 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -2692,6 +2692,7 @@ need_resume(VCHIQ_STATE_T *state)
static int
block_resume(VCHIQ_ARM_STATE_T *arm_state)
{
+ unsigned int bh;
int status = VCHIQ_SUCCESS;
const unsigned long timeout_val =
msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS);
@@ -2713,12 +2714,12 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
vchiq_log_error(vchiq_susp_log_level, "%s wait for "
"previously blocked clients failed", __func__);
status = VCHIQ_ERROR;
- write_lock_bh(&arm_state->susp_res_lock);
+ write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
goto out;
}
vchiq_log_info(vchiq_susp_log_level, "%s previously blocked "
"clients resumed", __func__);
- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
}

/* We need to wait for resume to complete if it's in process */
@@ -2730,7 +2731,7 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
"many times for resume", __func__);
goto out;
}
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);
vchiq_log_info(vchiq_susp_log_level, "%s wait for resume",
__func__);
if (wait_for_completion_interruptible_timeout(
@@ -2741,11 +2742,11 @@ block_resume(VCHIQ_ARM_STATE_T *arm_state)
resume_state_names[arm_state->vc_resume_state +
VC_RESUME_NUM_OFFSET]);
status = VCHIQ_ERROR;
- write_lock_bh(&arm_state->susp_res_lock);
+ write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
goto out;
}
vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__);
- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
resume_count++;
}
reinit_completion(&arm_state->resume_blocker);
@@ -2816,6 +2817,7 @@ vchiq_arm_vcsuspend(VCHIQ_STATE_T *state)
void
vchiq_platform_check_suspend(VCHIQ_STATE_T *state)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
int susp = 0;

@@ -2824,13 +2826,13 @@ vchiq_platform_check_suspend(VCHIQ_STATE_T *state)

vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);

- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (arm_state->vc_suspend_state == VC_SUSPEND_REQUESTED &&
arm_state->vc_resume_state == VC_RESUME_RESUMED) {
set_suspend_state(arm_state, VC_SUSPEND_IN_PROGRESS);
susp = 1;
}
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);

if (susp)
vchiq_platform_suspend(state);
@@ -2888,6 +2890,7 @@ output_timeout_error(VCHIQ_STATE_T *state)
VCHIQ_STATUS_T
vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T status = VCHIQ_ERROR;
long rc = 0;
@@ -2898,7 +2901,7 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)

vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);

- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);

status = block_resume(arm_state);
if (status != VCHIQ_SUCCESS)
@@ -2944,7 +2947,7 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
&arm_state->vc_suspend_complete,
msecs_to_jiffies(FORCE_SUSPEND_TIMEOUT_MS));

- write_lock_bh(&arm_state->susp_res_lock);
+ write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (rc < 0) {
vchiq_log_warning(vchiq_susp_log_level, "%s "
"interrupted waiting for suspend", __func__);
@@ -2989,7 +2992,7 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
unblock_resume(arm_state);

unlock:
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);

out:
vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, status);
@@ -2999,6 +3002,7 @@ vchiq_arm_force_suspend(VCHIQ_STATE_T *state)
void
vchiq_check_suspend(VCHIQ_STATE_T *state)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);

if (!arm_state)
@@ -3006,13 +3010,13 @@ vchiq_check_suspend(VCHIQ_STATE_T *state)

vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);

- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (arm_state->vc_suspend_state != VC_SUSPEND_SUSPENDED &&
arm_state->first_connect &&
!vchiq_videocore_wanted(state)) {
vchiq_arm_vcsuspend(state);
}
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);

out:
vchiq_log_trace(vchiq_susp_log_level, "%s exit", __func__);
@@ -3021,6 +3025,8 @@ vchiq_check_suspend(VCHIQ_STATE_T *state)
int
vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
{
+ unsigned int bh;
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
int resume = 0;
int ret = -1;
@@ -3030,10 +3036,10 @@ vchiq_arm_allow_resume(VCHIQ_STATE_T *state)

vchiq_log_trace(vchiq_susp_log_level, "%s", __func__);

- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
unblock_resume(arm_state);
resume = vchiq_check_resume(state);
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);

if (resume) {
if (wait_for_completion_interruptible(
@@ -3046,7 +3052,7 @@ vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
}
}

- read_lock_bh(&arm_state->susp_res_lock);
+ bh = read_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (arm_state->vc_suspend_state == VC_SUSPEND_SUSPENDED) {
vchiq_log_info(vchiq_susp_log_level,
"%s: Videocore remains suspended", __func__);
@@ -3055,7 +3061,7 @@ vchiq_arm_allow_resume(VCHIQ_STATE_T *state)
"%s: Videocore resumed", __func__);
ret = 0;
}
- read_unlock_bh(&arm_state->susp_res_lock);
+ read_unlock_bh(&arm_state->susp_res_lock, bh);
out:
vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
return ret;
@@ -3088,6 +3094,7 @@ VCHIQ_STATUS_T
vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
enum USE_TYPE_E use_type)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
char entity[16];
@@ -3114,7 +3121,7 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
goto out;
}

- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
while (arm_state->resume_blocked) {
/* If we call 'use' while force suspend is waiting for suspend,
* then we're about to block the thread which the force is
@@ -3143,14 +3150,14 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
"wait for resume blocker interrupted",
__func__, entity);
ret = VCHIQ_ERROR;
- write_lock_bh(&arm_state->susp_res_lock);
+ write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
arm_state->blocked_count--;
write_unlock_bh(&arm_state->susp_res_lock);
goto out;
}
vchiq_log_info(vchiq_susp_log_level, "%s %s resume "
"unblocked", __func__, entity);
- write_lock_bh(&arm_state->susp_res_lock);
+ write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (--arm_state->blocked_count == 0)
complete_all(&arm_state->blocked_blocker);
}
@@ -3179,7 +3186,7 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
"%s %s count %d, state count %d",
__func__, entity, *entity_uc, local_uc);

- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);

/* Completion is in a done state when we're not suspended, so this won't
* block for the non-suspended case. */
@@ -3220,6 +3227,7 @@ vchiq_use_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service,
VCHIQ_STATUS_T
vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
VCHIQ_STATUS_T ret = VCHIQ_SUCCESS;
char entity[16];
@@ -3241,7 +3249,7 @@ vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
entity_uc = &arm_state->peer_use_count;
}

- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (!arm_state->videocore_use_count || !(*entity_uc)) {
/* Don't use BUG_ON - don't allow user thread to crash kernel */
WARN_ON(!arm_state->videocore_use_count);
@@ -3272,7 +3280,7 @@ vchiq_release_internal(VCHIQ_STATE_T *state, VCHIQ_SERVICE_T *service)
arm_state->videocore_use_count);

unlock:
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);

out:
vchiq_log_trace(vchiq_susp_log_level, "%s exit %d", __func__, ret);
@@ -3419,6 +3427,7 @@ struct service_data_struct {
void
vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);
struct service_data_struct *service_data;
int i, found = 0;
@@ -3441,7 +3450,7 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
if (!service_data)
return;

- read_lock_bh(&arm_state->susp_res_lock);
+ bh = read_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
vc_suspend_state = arm_state->vc_suspend_state;
vc_resume_state = arm_state->vc_resume_state;
peer_count = arm_state->peer_use_count;
@@ -3470,7 +3479,7 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
break;
}

- read_unlock_bh(&arm_state->susp_res_lock);
+ read_unlock_bh(&arm_state->susp_res_lock, bh);

vchiq_log_warning(vchiq_susp_log_level,
"-- Videcore suspend state: %s --",
@@ -3505,6 +3514,7 @@ vchiq_dump_service_use_state(VCHIQ_STATE_T *state)
VCHIQ_STATUS_T
vchiq_check_service(VCHIQ_SERVICE_T *service)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state;
VCHIQ_STATUS_T ret = VCHIQ_ERROR;

@@ -3515,10 +3525,10 @@ vchiq_check_service(VCHIQ_SERVICE_T *service)

arm_state = vchiq_platform_get_arm_state(service->state);

- read_lock_bh(&arm_state->susp_res_lock);
+ bh = read_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (service->service_use_count)
ret = VCHIQ_SUCCESS;
- read_unlock_bh(&arm_state->susp_res_lock);
+ read_unlock_bh(&arm_state->susp_res_lock, bh);

if (ret == VCHIQ_ERROR) {
vchiq_log_error(vchiq_susp_log_level,
@@ -3544,17 +3554,18 @@ void vchiq_on_remote_use_active(VCHIQ_STATE_T *state)
void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
VCHIQ_CONNSTATE_T oldstate, VCHIQ_CONNSTATE_T newstate)
{
+ unsigned int bh;
VCHIQ_ARM_STATE_T *arm_state = vchiq_platform_get_arm_state(state);

vchiq_log_info(vchiq_susp_log_level, "%d: %s->%s", state->id,
get_conn_state_name(oldstate), get_conn_state_name(newstate));
if (state->conn_state == VCHIQ_CONNSTATE_CONNECTED) {
- write_lock_bh(&arm_state->susp_res_lock);
+ bh = write_lock_bh(&arm_state->susp_res_lock, SOFTIRQ_ALL_MASK);
if (!arm_state->first_connect) {
char threadname[16];

arm_state->first_connect = 1;
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);
snprintf(threadname, sizeof(threadname), "vchiq-keep/%d",
state->id);
arm_state->ka_thread = kthread_create(
@@ -3569,7 +3580,7 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
wake_up_process(arm_state->ka_thread);
}
} else
- write_unlock_bh(&arm_state->susp_res_lock);
+ write_unlock_bh(&arm_state->susp_res_lock, bh);
}
}

diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 7d9eea7..1137e8c 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -598,10 +598,11 @@ static void o2net_set_nn_state(struct o2net_node *nn,
/* see o2net_register_callbacks() */
static void o2net_data_ready(struct sock *sk)
{
+ unsigned int bh;
void (*ready)(struct sock *sk);
struct o2net_sock_container *sc;

- read_lock_bh(&sk->sk_callback_lock);
+ bh = read_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sc = sk->sk_user_data;
if (sc) {
sclog(sc, "data_ready hit\n");
@@ -611,7 +612,7 @@ static void o2net_data_ready(struct sock *sk)
} else {
ready = sk->sk_data_ready;
}
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);

ready(sk);
}
@@ -619,10 +620,11 @@ static void o2net_data_ready(struct sock *sk)
/* see o2net_register_callbacks() */
static void o2net_state_change(struct sock *sk)
{
+ unsigned int bh;
void (*state_change)(struct sock *sk);
struct o2net_sock_container *sc;

- read_lock_bh(&sk->sk_callback_lock);
+ bh = read_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sc = sk->sk_user_data;
if (sc == NULL) {
state_change = sk->sk_state_change;
@@ -649,7 +651,7 @@ static void o2net_state_change(struct sock *sk)
break;
}
out:
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);
state_change(sk);
}

@@ -661,7 +663,8 @@ static void o2net_state_change(struct sock *sk)
static void o2net_register_callbacks(struct sock *sk,
struct o2net_sock_container *sc)
{
- write_lock_bh(&sk->sk_callback_lock);
+ unsigned int bh;
+ bh = write_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);

/* accepted sockets inherit the old listen socket data ready */
if (sk->sk_data_ready == o2net_listen_data_ready) {
@@ -680,22 +683,23 @@ static void o2net_register_callbacks(struct sock *sk,

mutex_init(&sc->sc_send_lock);

- write_unlock_bh(&sk->sk_callback_lock);
+ write_unlock_bh(&sk->sk_callback_lock, bh);
}

static int o2net_unregister_callbacks(struct sock *sk,
struct o2net_sock_container *sc)
{
+ unsigned int bh;
int ret = 0;

- write_lock_bh(&sk->sk_callback_lock);
+ bh = write_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
if (sk->sk_user_data == sc) {
ret = 1;
sk->sk_user_data = NULL;
sk->sk_data_ready = sc->sc_data_ready;
sk->sk_state_change = sc->sc_state_change;
}
- write_unlock_bh(&sk->sk_callback_lock);
+ write_unlock_bh(&sk->sk_callback_lock, bh);

return ret;
}
@@ -1986,9 +1990,10 @@ static void o2net_accept_many(struct work_struct *work)

static void o2net_listen_data_ready(struct sock *sk)
{
+ unsigned int bh;
void (*ready)(struct sock *sk);

- read_lock_bh(&sk->sk_callback_lock);
+ bh = read_lock_bh(&sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
ready = sk->sk_user_data;
if (ready == NULL) { /* check for teardown race */
ready = sk->sk_data_ready;
@@ -2015,13 +2020,14 @@ static void o2net_listen_data_ready(struct sock *sk)
}

out:
- read_unlock_bh(&sk->sk_callback_lock);
+ read_unlock_bh(&sk->sk_callback_lock, bh);
if (ready != NULL)
ready(sk);
}

static int o2net_open_listening_sock(__be32 addr, __be16 port)
{
+ unsigned int bh;
struct socket *sock = NULL;
int ret;
struct sockaddr_in sin = {
@@ -2038,10 +2044,10 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)

sock->sk->sk_allocation = GFP_ATOMIC;

- write_lock_bh(&sock->sk->sk_callback_lock);
+ bh = write_lock_bh(&sock->sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sock->sk->sk_user_data = sock->sk->sk_data_ready;
sock->sk->sk_data_ready = o2net_listen_data_ready;
- write_unlock_bh(&sock->sk->sk_callback_lock);
+ write_unlock_bh(&sock->sk->sk_callback_lock, bh);

o2net_listen_sock = sock;
INIT_WORK(&o2net_listen_work, o2net_accept_many);
@@ -2104,6 +2110,7 @@ int o2net_start_listening(struct o2nm_node *node)
* tearing it down */
void o2net_stop_listening(struct o2nm_node *node)
{
+ unsigned int bh;
struct socket *sock = o2net_listen_sock;
size_t i;

@@ -2111,10 +2118,10 @@ void o2net_stop_listening(struct o2nm_node *node)
BUG_ON(o2net_listen_sock == NULL);

/* stop the listening socket from generating work */
- write_lock_bh(&sock->sk->sk_callback_lock);
+ bh = write_lock_bh(&sock->sk->sk_callback_lock, SOFTIRQ_ALL_MASK);
sock->sk->sk_data_ready = sock->sk->sk_user_data;
sock->sk->sk_user_data = NULL;
- write_unlock_bh(&sock->sk->sk_callback_lock);
+ write_unlock_bh(&sock->sk->sk_callback_lock, bh);

for (i = 0; i < ARRAY_SIZE(o2net_nodes); i++) {
struct o2nm_node *node = o2nm_get_node_by_num(i);
diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index 3dcd617..cda528b 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -99,9 +99,9 @@ do { \
#endif

#define read_lock_irq(lock) _raw_read_lock_irq(lock)
-#define read_lock_bh(lock) _raw_read_lock_bh(lock)
+#define read_lock_bh(lock, mask) _raw_read_lock_bh(lock, mask)
#define write_lock_irq(lock) _raw_write_lock_irq(lock)
-#define write_lock_bh(lock) _raw_write_lock_bh(lock)
+#define write_lock_bh(lock, mask) _raw_write_lock_bh(lock, mask)
#define read_unlock(lock) _raw_read_unlock(lock)
#define write_unlock(lock) _raw_write_unlock(lock)
#define read_unlock_irq(lock) _raw_read_unlock_irq(lock)
@@ -112,14 +112,14 @@ do { \
typecheck(unsigned long, flags); \
_raw_read_unlock_irqrestore(lock, flags); \
} while (0)
-#define read_unlock_bh(lock) _raw_read_unlock_bh(lock)
+#define read_unlock_bh(lock, bh) _raw_read_unlock_bh(lock, bh)

#define write_unlock_irqrestore(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_raw_write_unlock_irqrestore(lock, flags); \
} while (0)
-#define write_unlock_bh(lock) _raw_write_unlock_bh(lock)
+#define write_unlock_bh(lock, bh) _raw_write_unlock_bh(lock, bh)

#define write_trylock_irqsave(lock, flags) \
({ \
diff --git a/include/linux/rwlock_api_smp.h b/include/linux/rwlock_api_smp.h
index 86ebb4b..fb66489 100644
--- a/include/linux/rwlock_api_smp.h
+++ b/include/linux/rwlock_api_smp.h
@@ -17,8 +17,8 @@

void __lockfunc _raw_read_lock(rwlock_t *lock) __acquires(lock);
void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock);
-void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock);
-void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock);
+unsigned int __lockfunc _raw_read_lock_bh(rwlock_t *lock, unsigned int mask) __acquires(lock);
+unsigned int __lockfunc _raw_write_lock_bh(rwlock_t *lock, unsigned int mask) __acquires(lock);
void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock);
void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock);
unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock)
@@ -29,8 +29,8 @@ int __lockfunc _raw_read_trylock(rwlock_t *lock);
int __lockfunc _raw_write_trylock(rwlock_t *lock);
void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock);
void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock);
-void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock);
-void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock);
+void __lockfunc _raw_read_unlock_bh(rwlock_t *lock, unsigned int bh) __releases(lock);
+void __lockfunc _raw_write_unlock_bh(rwlock_t *lock, unsigned int bh) __releases(lock);
void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock);
void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock);
void __lockfunc
@@ -49,11 +49,11 @@ _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
#endif

#ifdef CONFIG_INLINE_READ_LOCK_BH
-#define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock)
+#define _raw_read_lock_bh(lock, mask) __raw_read_lock_bh(lock, mask)
#endif

#ifdef CONFIG_INLINE_WRITE_LOCK_BH
-#define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock)
+#define _raw_write_lock_bh(lock, mask) __raw_write_lock_bh(lock, mask)
#endif

#ifdef CONFIG_INLINE_READ_LOCK_IRQ
@@ -89,11 +89,11 @@ _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
#endif

#ifdef CONFIG_INLINE_READ_UNLOCK_BH
-#define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock)
+#define _raw_read_unlock_bh(lock, bh) __raw_read_unlock_bh(lock, bh)
#endif

#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH
-#define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock)
+#define _raw_write_unlock_bh(lock, bh) __raw_write_unlock_bh(lock, bh)
#endif

#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ
@@ -170,11 +170,13 @@ static inline void __raw_read_lock_irq(rwlock_t *lock)
LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
}

-static inline void __raw_read_lock_bh(rwlock_t *lock)
+static inline unsigned int __raw_read_lock_bh(rwlock_t *lock,
+ unsigned int mask)
{
__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
+ return 0;
}

static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock)
@@ -197,11 +199,13 @@ static inline void __raw_write_lock_irq(rwlock_t *lock)
LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
}

-static inline void __raw_write_lock_bh(rwlock_t *lock)
+static inline unsigned int __raw_write_lock_bh(rwlock_t *lock,
+ unsigned int mask)
{
__local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
+ return 0;
}

static inline void __raw_write_lock(rwlock_t *lock)
@@ -244,7 +248,8 @@ static inline void __raw_read_unlock_irq(rwlock_t *lock)
preempt_enable();
}

-static inline void __raw_read_unlock_bh(rwlock_t *lock)
+static inline void __raw_read_unlock_bh(rwlock_t *lock,
+ unsigned int bh)
{
rwlock_release(&lock->dep_map, 1, _RET_IP_);
do_raw_read_unlock(lock);
@@ -268,7 +273,8 @@ static inline void __raw_write_unlock_irq(rwlock_t *lock)
preempt_enable();
}

-static inline void __raw_write_unlock_bh(rwlock_t *lock)
+static inline void __raw_write_unlock_bh(rwlock_t *lock,
+ unsigned int bh)
{
rwlock_release(&lock->dep_map, 1, _RET_IP_);
do_raw_write_unlock(lock);
diff --git a/include/linux/spinlock_api_up.h b/include/linux/spinlock_api_up.h
index a4b6124..e2bfafe 100644
--- a/include/linux/spinlock_api_up.h
+++ b/include/linux/spinlock_api_up.h
@@ -61,7 +61,7 @@
#define _raw_write_lock(lock) __LOCK(lock)
#define _raw_spin_lock_bh(lock) ({ __LOCK_BH(lock); 0; }, SOFTIRQ_ALL_MASK)
#define _raw_read_lock_bh(lock) ({ __LOCK_BH(lock); 0; })
-#define _raw_write_lock_bh(lock) ({ __LOCK_BH(lock); 0; })
+#define _raw_write_lock_bh(lock) ({ __LOCK_BH(lock); 0; }, SOFTIRQ_ALL_MASK)
#define _raw_spin_lock_irq(lock) __LOCK_IRQ(lock)
#define _raw_read_lock_irq(lock) __LOCK_IRQ(lock)
#define _raw_write_lock_irq(lock) __LOCK_IRQ(lock)
--
2.7.4