Skip to content

Commit

Permalink
Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/tip/tip

Pull core locking changes from Ingo Molnar:
 "The biggest changes:

   - add lockdep support for seqcount/seqlocks structures, this
     unearthed both bugs and required extra annotation.

   - move the various kernel locking primitives to the new
     kernel/locking/ directory"

* 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits)
  block: Use u64_stats_init() to initialize seqcounts
  locking/lockdep: Mark __lockdep_count_forward_deps() as static
  lockdep/proc: Fix lock-time avg computation
  locking/doc: Update references to kernel/mutex.c
  ipv6: Fix possible ipv6 seqlock deadlock
  cpuset: Fix potential deadlock w/ set_mems_allowed
  seqcount: Add lockdep functionality to seqcount/seqlock structures
  net: Explicitly initialize u64_stats_sync structures for lockdep
  locking: Move the percpu-rwsem code to kernel/locking/
  locking: Move the lglocks code to kernel/locking/
  locking: Move the rwsem code to kernel/locking/
  locking: Move the rtmutex code to kernel/locking/
  locking: Move the semaphore core to kernel/locking/
  locking: Move the spinlock code to kernel/locking/
  locking: Move the lockdep code to kernel/locking/
  locking: Move the mutex code to kernel/locking/
  hung_task debugging: Add tracepoint to report the hang
  x86/locking/kconfig: Update paravirt spinlock Kconfig description
  lockstat: Report avg wait and hold times
  lockdep, x86/alternatives: Drop ancient lockdep fixup message
  ...
  • Loading branch information
torvalds committed Nov 14, 2013
2 parents 7971e23 + 90d3839 commit 5e30025
Show file tree
Hide file tree
Showing 83 changed files with 534 additions and 148 deletions.
2 changes: 1 addition & 1 deletion Documentation/DocBook/kernel-locking.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -1958,7 +1958,7 @@ machines due to caching.
<chapter id="apiref-mutex">
<title>Mutex API reference</title>
!Iinclude/linux/mutex.h
!Ekernel/mutex.c
!Ekernel/locking/mutex.c
</chapter>

<chapter id="apiref-futex">
Expand Down
123 changes: 61 additions & 62 deletions Documentation/lockstat.txt

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Documentation/mutex-design.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ using mutexes at the moment, please let me know if you find any. ]
Implementation of mutexes
-------------------------

'struct mutex' is the new mutex type, defined in include/linux/mutex.h
and implemented in kernel/mutex.c. It is a counter-based mutex with a
spinlock and a wait-list. The counter has 3 states: 1 for "unlocked",
0 for "locked" and negative numbers (usually -1) for "locked, potential
waiters queued".
'struct mutex' is the new mutex type, defined in include/linux/mutex.h and
implemented in kernel/locking/mutex.c. It is a counter-based mutex with a
spinlock and a wait-list. The counter has 3 states: 1 for "unlocked", 0 for
"locked" and negative numbers (usually -1) for "locked, potential waiters
queued".

the APIs of 'struct mutex' have been streamlined:

Expand Down
6 changes: 3 additions & 3 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,10 @@ config PARAVIRT_SPINLOCKS
spinlock implementation with something virtualization-friendly
(for example, block the virtual CPU rather than spinning).

Unfortunately the downside is an up to 5% performance hit on
native kernels, with various workloads.
It has a minimal impact on native kernels and gives a nice performance
benefit on paravirtualized KVM / Xen kernels.

If you are unsure how to answer this question, answer N.
If you are unsure how to answer this question, answer Y.

source "arch/x86/xen/Kconfig"

Expand Down
11 changes: 0 additions & 11 deletions arch/x86/kernel/alternative.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,17 +402,6 @@ void alternatives_enable_smp(void)
{
struct smp_alt_module *mod;

#ifdef CONFIG_LOCKDEP
/*
* Older binutils section handling bug prevented
* alternatives-replacement from working reliably.
*
* If this still occurs then you should see a hang
* or crash shortly after this line:
*/
pr_info("lockdep: fixing up alternatives\n");
#endif

/* Why bother if there are no other CPUs? */
BUG_ON(num_possible_cpus() == 1);

Expand Down
8 changes: 4 additions & 4 deletions arch/x86/vdso/vclock_gettime.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ notrace static int __always_inline do_realtime(struct timespec *ts)

ts->tv_nsec = 0;
do {
seq = read_seqcount_begin(&gtod->seq);
seq = read_seqcount_begin_no_lockdep(&gtod->seq);
mode = gtod->clock.vclock_mode;
ts->tv_sec = gtod->wall_time_sec;
ns = gtod->wall_time_snsec;
Expand All @@ -198,7 +198,7 @@ notrace static int do_monotonic(struct timespec *ts)

ts->tv_nsec = 0;
do {
seq = read_seqcount_begin(&gtod->seq);
seq = read_seqcount_begin_no_lockdep(&gtod->seq);
mode = gtod->clock.vclock_mode;
ts->tv_sec = gtod->monotonic_time_sec;
ns = gtod->monotonic_time_snsec;
Expand All @@ -214,7 +214,7 @@ notrace static int do_realtime_coarse(struct timespec *ts)
{
unsigned long seq;
do {
seq = read_seqcount_begin(&gtod->seq);
seq = read_seqcount_begin_no_lockdep(&gtod->seq);
ts->tv_sec = gtod->wall_time_coarse.tv_sec;
ts->tv_nsec = gtod->wall_time_coarse.tv_nsec;
} while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
Expand All @@ -225,7 +225,7 @@ notrace static int do_monotonic_coarse(struct timespec *ts)
{
unsigned long seq;
do {
seq = read_seqcount_begin(&gtod->seq);
seq = read_seqcount_begin_no_lockdep(&gtod->seq);
ts->tv_sec = gtod->monotonic_time_coarse.tv_sec;
ts->tv_nsec = gtod->monotonic_time_coarse.tv_nsec;
} while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
Expand Down
10 changes: 10 additions & 0 deletions block/blk-cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,11 @@ struct request_list *__blk_queue_next_rl(struct request_list *rl,
#define blk_queue_for_each_rl(rl, q) \
for ((rl) = &(q)->root_rl; (rl); (rl) = __blk_queue_next_rl((rl), (q)))

static inline void blkg_stat_init(struct blkg_stat *stat)
{
u64_stats_init(&stat->syncp);
}

/**
* blkg_stat_add - add a value to a blkg_stat
* @stat: target blkg_stat
Expand Down Expand Up @@ -458,6 +463,11 @@ static inline void blkg_stat_merge(struct blkg_stat *to, struct blkg_stat *from)
blkg_stat_add(to, blkg_stat_read(from));
}

static inline void blkg_rwstat_init(struct blkg_rwstat *rwstat)
{
u64_stats_init(&rwstat->syncp);
}

/**
* blkg_rwstat_add - add a value to a blkg_rwstat
* @rwstat: target blkg_rwstat
Expand Down
10 changes: 10 additions & 0 deletions block/blk-throttle.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ static struct throtl_data *sq_to_td(struct throtl_service_queue *sq)
} \
} while (0)

static void tg_stats_init(struct tg_stats_cpu *tg_stats)
{
blkg_rwstat_init(&tg_stats->service_bytes);
blkg_rwstat_init(&tg_stats->serviced);
}

/*
* Worker for allocating per cpu stat for tgs. This is scheduled on the
* system_wq once there are some groups on the alloc_list waiting for
Expand All @@ -269,12 +275,16 @@ static void tg_stats_alloc_fn(struct work_struct *work)

alloc_stats:
if (!stats_cpu) {
int cpu;

stats_cpu = alloc_percpu(struct tg_stats_cpu);
if (!stats_cpu) {
/* allocation failed, try again after some time */
schedule_delayed_work(dwork, msecs_to_jiffies(10));
return;
}
for_each_possible_cpu(cpu)
tg_stats_init(per_cpu_ptr(stats_cpu, cpu));
}

spin_lock_irq(&tg_stats_alloc_lock);
Expand Down
25 changes: 25 additions & 0 deletions block/cfq-iosched.c
Original file line number Diff line number Diff line change
Expand Up @@ -1508,13 +1508,38 @@ static void cfq_init_cfqg_base(struct cfq_group *cfqg)
}

#ifdef CONFIG_CFQ_GROUP_IOSCHED
static void cfqg_stats_init(struct cfqg_stats *stats)
{
blkg_rwstat_init(&stats->service_bytes);
blkg_rwstat_init(&stats->serviced);
blkg_rwstat_init(&stats->merged);
blkg_rwstat_init(&stats->service_time);
blkg_rwstat_init(&stats->wait_time);
blkg_rwstat_init(&stats->queued);

blkg_stat_init(&stats->sectors);
blkg_stat_init(&stats->time);

#ifdef CONFIG_DEBUG_BLK_CGROUP
blkg_stat_init(&stats->unaccounted_time);
blkg_stat_init(&stats->avg_queue_size_sum);
blkg_stat_init(&stats->avg_queue_size_samples);
blkg_stat_init(&stats->dequeue);
blkg_stat_init(&stats->group_wait_time);
blkg_stat_init(&stats->idle_time);
blkg_stat_init(&stats->empty_time);
#endif
}

static void cfq_pd_init(struct blkcg_gq *blkg)
{
struct cfq_group *cfqg = blkg_to_cfqg(blkg);

cfq_init_cfqg_base(cfqg);
cfqg->weight = blkg->blkcg->cfq_weight;
cfqg->leaf_weight = blkg->blkcg->cfq_leaf_weight;
cfqg_stats_init(&cfqg->stats);
cfqg_stats_init(&cfqg->dead_stats);
}

static void cfq_pd_offline(struct blkcg_gq *blkg)
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,16 @@ static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev)

static int dummy_dev_init(struct net_device *dev)
{
int i;
dev->dstats = alloc_percpu(struct pcpu_dstats);
if (!dev->dstats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct pcpu_dstats *dstats;
dstats = per_cpu_ptr(dev->dstats, i);
u64_stats_init(&dstats->syncp);
}
return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2148,6 +2148,9 @@ static int be_tx_qs_create(struct be_adapter *adapter)
if (status)
return status;

u64_stats_init(&txo->stats.sync);
u64_stats_init(&txo->stats.sync_compl);

/* If num_evt_qs is less than num_tx_qs, then more than
* one txq share an eq
*/
Expand Down Expand Up @@ -2209,6 +2212,7 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
if (rc)
return rc;

u64_stats_init(&rxo->stats.sync);
eq = &adapter->eq_obj[i % adapter->num_evt_qs].q;
rc = be_cmd_cq_create(adapter, cq, eq, false, 3);
if (rc)
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/igb/igb_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1224,6 +1224,9 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
ring->count = adapter->tx_ring_count;
ring->queue_index = txr_idx;

u64_stats_init(&ring->tx_syncp);
u64_stats_init(&ring->tx_syncp2);

/* assign ring to adapter */
adapter->tx_ring[txr_idx] = ring;

Expand Down Expand Up @@ -1257,6 +1260,8 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
ring->count = adapter->rx_ring_count;
ring->queue_index = rxr_idx;

u64_stats_init(&ring->rx_syncp);

/* assign ring to adapter */
adapter->rx_ring[rxr_idx] = ring;
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5085,6 +5085,8 @@ int ixgbe_setup_tx_resources(struct ixgbe_ring *tx_ring)
if (!tx_ring->tx_buffer_info)
goto err;

u64_stats_init(&tx_ring->syncp);

/* round up to nearest 4K */
tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
Expand Down Expand Up @@ -5167,6 +5169,8 @@ int ixgbe_setup_rx_resources(struct ixgbe_ring *rx_ring)
if (!rx_ring->rx_buffer_info)
goto err;

u64_stats_init(&rx_ring->syncp);

/* Round up to nearest 4K */
rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc);
rx_ring->size = ALIGN(rx_ring->size, 4096);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/mvneta.c
Original file line number Diff line number Diff line change
Expand Up @@ -2792,6 +2792,9 @@ static int mvneta_probe(struct platform_device *pdev)

pp = netdev_priv(dev);

u64_stats_init(&pp->tx_stats.syncp);
u64_stats_init(&pp->rx_stats.syncp);

pp->weight = MVNETA_RX_POLL_WEIGHT;
pp->phy_node = phy_node;
pp->phy_interface = phy_mode;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/marvell/sky2.c
Original file line number Diff line number Diff line change
Expand Up @@ -4763,6 +4763,9 @@ static struct net_device *sky2_init_netdev(struct sky2_hw *hw, unsigned port,
sky2->hw = hw;
sky2->msg_enable = netif_msg_init(debug, default_msg);

u64_stats_init(&sky2->tx_stats.syncp);
u64_stats_init(&sky2->rx_stats.syncp);

/* Auto speed and flow control */
sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
if (hw->chip_id != CHIP_ID_YUKON_XL)
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/neterion/vxge/vxge-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,10 @@ static int vxge_open_vpaths(struct vxgedev *vdev)
vdev->config.tx_steering_type;
vpath->fifo.ndev = vdev->ndev;
vpath->fifo.pdev = vdev->pdev;

u64_stats_init(&vpath->fifo.stats.syncp);
u64_stats_init(&vpath->ring.stats.syncp);

if (vdev->config.tx_steering_type)
vpath->fifo.txq =
netdev_get_tx_queue(vdev->ndev, i);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/nvidia/forcedeth.c
Original file line number Diff line number Diff line change
Expand Up @@ -5619,6 +5619,8 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
spin_lock_init(&np->lock);
spin_lock_init(&np->hwstats_lock);
SET_NETDEV_DEV(dev, &pci_dev->dev);
u64_stats_init(&np->swstats_rx_syncp);
u64_stats_init(&np->swstats_tx_syncp);

init_timer(&np->oom_kick);
np->oom_kick.data = (unsigned long) dev;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/realtek/8139too.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,9 @@ static struct net_device *rtl8139_init_board(struct pci_dev *pdev)

pci_set_master (pdev);

u64_stats_init(&tp->rx_stats.syncp);
u64_stats_init(&tp->tx_stats.syncp);

retry:
/* PIO bar register comes first. */
bar = !use_io;
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/tile/tilepro.c
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,8 @@ static void tile_net_register(void *dev_ptr)
info->egress_timer.data = (long)info;
info->egress_timer.function = tile_net_handle_egress_timer;

u64_stats_init(&info->stats.syncp);

priv->cpu[my_cpu] = info;

/*
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/via/via-rhine.c
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,9 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

rp->base = ioaddr;

u64_stats_init(&rp->tx_stats.syncp);
u64_stats_init(&rp->rx_stats.syncp);

/* Get chip registers into a sane state */
rhine_power_init(dev);
rhine_hw_init(dev, pioaddr);
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ifb.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ MODULE_PARM_DESC(numifbs, "Number of ifb devices");
static int __init ifb_init_one(int index)
{
struct net_device *dev_ifb;
struct ifb_private *dp;
int err;

dev_ifb = alloc_netdev(sizeof(struct ifb_private),
Expand All @@ -273,6 +274,10 @@ static int __init ifb_init_one(int index)
if (!dev_ifb)
return -ENOMEM;

dp = netdev_priv(dev_ifb);
u64_stats_init(&dp->rsync);
u64_stats_init(&dp->tsync);

dev_ifb->rtnl_link_ops = &ifb_link_ops;
err = register_netdevice(dev_ifb);
if (err < 0)
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,16 @@ static const struct ethtool_ops loopback_ethtool_ops = {

static int loopback_dev_init(struct net_device *dev)
{
int i;
dev->lstats = alloc_percpu(struct pcpu_lstats);
if (!dev->lstats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct pcpu_lstats *lb_stats;
lb_stats = per_cpu_ptr(dev->lstats, i);
u64_stats_init(&lb_stats->syncp);
}
return 0;
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ static int macvlan_init(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);
const struct net_device *lowerdev = vlan->lowerdev;
int i;

dev->state = (dev->state & ~MACVLAN_STATE_MASK) |
(lowerdev->state & MACVLAN_STATE_MASK);
Expand All @@ -549,6 +550,12 @@ static int macvlan_init(struct net_device *dev)
if (!vlan->pcpu_stats)
return -ENOMEM;

for_each_possible_cpu(i) {
struct macvlan_pcpu_stats *mvlstats;
mvlstats = per_cpu_ptr(vlan->pcpu_stats, i);
u64_stats_init(&mvlstats->syncp);
}

return 0;
}

Expand Down
Loading

0 comments on commit 5e30025

Please sign in to comment.