PHONY += headers_check
headers_check: headers_install
$(Q)$(MAKE) $(hdr-inst)=include/uapi HDRCHECK=1
- $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi/ $(hdr-dst) HDRCHECK=1
+ $(Q)$(MAKE) $(hdr-inst)=arch/$(hdr-arch)/include/uapi $(hdr-dst) HDRCHECK=1
# ---------------------------------------------------------------------------
# Kernel selftest
struct cpuinfo_x86 *c = &cpu_data(cpu);
struct platform_data *pdata;
+ /*
+ * Don't execute this on resume as the offline callback did
+ * not get executed on suspend.
+ */
+ if (cpuhp_tasks_frozen)
+ return 0;
+
/*
* CPUID.06H.EAX[0] indicates whether the CPU has thermal
* sensors. We check this bit only, all the early CPUs
struct temp_data *tdata;
int indx, target;
+ /*
+ * Don't execute this on suspend as the device remove locks
+ * up the machine.
+ */
+ if (cpuhp_tasks_frozen)
+ return 0;
+
/* If the physical CPU device does not exist, just return */
if (!pdev)
return 0;
rc = -EINVAL;
goto out;
}
- drv_data->irq = irq_of_parse_and_map(np, 0);
drv_data->rstc = devm_reset_control_get_optional(dev, NULL);
if (IS_ERR(drv_data->rstc)) {
if (!IS_ERR(drv_data->clk))
clk_prepare_enable(drv_data->clk);
+ drv_data->irq = platform_get_irq(pd, 0);
+
if (pdata) {
drv_data->freq_m = pdata->freq_m;
drv_data->freq_n = pdata->freq_n;
- drv_data->irq = platform_get_irq(pd, 0);
drv_data->adapter.timeout = msecs_to_jiffies(pdata->timeout);
drv_data->offload_enabled = false;
memcpy(&drv_data->reg_offsets, &mv64xxx_i2c_regs_mv64xxx, sizeof(drv_data->reg_offsets));
goto exit_clk;
}
if (drv_data->irq < 0) {
- rc = -ENXIO;
+ rc = drv_data->irq;
goto exit_reset;
}
adapter->class = I2C_CLASS_HWMON;
adapter->dev.parent = &pdev->dev;
adapter->dev.of_node = pdev->dev.of_node;
+ ACPI_COMPANION_SET(&adapter->dev, ACPI_COMPANION(&pdev->dev));
i2c_set_adapdata(adapter, ctx);
rc = i2c_add_adapter(adapter);
if (rc) {
if (force_nr) {
priv->adap.nr = force_nr;
ret = i2c_add_numbered_adapter(&priv->adap);
- dev_err(&parent->dev,
- "failed to add mux-adapter %u as bus %u (error=%d)\n",
- chan_id, force_nr, ret);
+ if (ret < 0) {
+ dev_err(&parent->dev,
+ "failed to add mux-adapter %u as bus %u (error=%d)\n",
+ chan_id, force_nr, ret);
+ goto err_free_priv;
+ }
} else {
ret = i2c_add_adapter(&priv->adap);
- dev_err(&parent->dev,
- "failed to add mux-adapter %u (error=%d)\n",
- chan_id, ret);
- }
- if (ret < 0) {
- kfree(priv);
- return ret;
+ if (ret < 0) {
+ dev_err(&parent->dev,
+ "failed to add mux-adapter %u (error=%d)\n",
+ chan_id, ret);
+ goto err_free_priv;
+ }
}
WARN(sysfs_create_link(&priv->adap.dev.kobj, &muxc->dev->kobj,
muxc->adapter[muxc->num_adapters++] = &priv->adap;
return 0;
+
+err_free_priv:
+ kfree(priv);
+ return ret;
}
EXPORT_SYMBOL_GPL(i2c_mux_add_adapter);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mux->data.reg_size = resource_size(res);
mux->data.reg = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(mux->data.reg))
- return PTR_ERR(mux->data.reg);
+ if (IS_ERR(mux->data.reg)) {
+ ret = PTR_ERR(mux->data.reg);
+ goto err_put_parent;
+ }
}
if (mux->data.reg_size != 4 && mux->data.reg_size != 2 &&
mux->data.reg_size != 1) {
dev_err(&pdev->dev, "Invalid register size\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_put_parent;
}
muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 0, 0,
i2c_mux_reg_select, NULL);
- if (!muxc)
- return -ENOMEM;
+ if (!muxc) {
+ ret = -ENOMEM;
+ goto err_put_parent;
+ }
muxc->priv = mux;
platform_set_drvdata(pdev, muxc);
ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class);
if (ret)
- goto add_adapter_failed;
+ goto err_del_mux_adapters;
}
dev_dbg(&pdev->dev, "%d port mux on %s adapter\n",
return 0;
-add_adapter_failed:
+err_del_mux_adapters:
i2c_mux_del_adapters(muxc);
+err_put_parent:
+ i2c_put_adapter(parent);
return ret;
}
* Buffers are freed after this timeout
*/
static unsigned dm_bufio_max_age = DM_BUFIO_DEFAULT_AGE_SECS;
-static unsigned dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
+static unsigned long dm_bufio_retain_bytes = DM_BUFIO_DEFAULT_RETAIN_BYTES;
static unsigned long dm_bufio_peak_allocated;
static unsigned long dm_bufio_allocated_kmem_cache;
return true;
}
-static unsigned get_retain_buffers(struct dm_bufio_client *c)
+static unsigned long get_retain_buffers(struct dm_bufio_client *c)
{
- unsigned retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
- return retain_bytes / c->block_size;
+ unsigned long retain_bytes = ACCESS_ONCE(dm_bufio_retain_bytes);
+ return retain_bytes >> (c->sectors_per_block_bits + SECTOR_SHIFT);
}
static unsigned long __scan(struct dm_bufio_client *c, unsigned long nr_to_scan,
struct dm_buffer *b, *tmp;
unsigned long freed = 0;
unsigned long count = nr_to_scan;
- unsigned retain_target = get_retain_buffers(c);
+ unsigned long retain_target = get_retain_buffers(c);
for (l = 0; l < LIST_SIZE; l++) {
list_for_each_entry_safe_reverse(b, tmp, &c->lru[l], lru_list) {
static void __evict_old_buffers(struct dm_bufio_client *c, unsigned long age_hz)
{
struct dm_buffer *b, *tmp;
- unsigned retain_target = get_retain_buffers(c);
- unsigned count;
+ unsigned long retain_target = get_retain_buffers(c);
+ unsigned long count;
LIST_HEAD(write_list);
dm_bufio_lock(c);
module_param_named(max_age_seconds, dm_bufio_max_age, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(max_age_seconds, "Max age of a buffer in seconds");
-module_param_named(retain_bytes, dm_bufio_retain_bytes, uint, S_IRUGO | S_IWUSR);
+module_param_named(retain_bytes, dm_bufio_retain_bytes, ulong, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(retain_bytes, "Try to keep at least this many bytes cached in memory");
module_param_named(peak_allocated_bytes, dm_bufio_peak_allocated, ulong, S_IRUGO | S_IWUSR);
{
struct background_tracker *b = kmalloc(sizeof(*b), GFP_KERNEL);
+ if (!b) {
+ DMERR("couldn't create background_tracker");
+ return NULL;
+ }
+
b->max_work = max_work;
atomic_set(&b->pending_promotes, 0);
atomic_set(&b->pending_writebacks, 0);
* Cache entries may not be populated. So we cannot rely on the
* size of the clean queue.
*/
- unsigned nr_clean;
-
if (idle) {
/*
* We'd like to clean everything.
return q_size(&mq->dirty) == 0u;
}
- nr_clean = from_cblock(mq->cache_size) - q_size(&mq->dirty);
- return (nr_clean + btracker_nr_writebacks_queued(mq->bg_work)) >=
- percent_to_target(mq, CLEAN_TARGET);
+ /*
+ * If we're busy we don't worry about cleaning at all.
+ */
+ return true;
}
-static bool free_target_met(struct smq_policy *mq, bool idle)
+static bool free_target_met(struct smq_policy *mq)
{
unsigned nr_free;
- if (!idle)
- return true;
-
nr_free = from_cblock(mq->cache_size) - mq->cache_alloc.nr_allocated;
return (nr_free + btracker_nr_demotions_queued(mq->bg_work)) >=
percent_to_target(mq, FREE_TARGET);
if (unlikely(WARN_ON_ONCE(!mq->migrations_allowed)))
return;
- e = q_peek(&mq->clean, mq->clean.nr_levels, true);
+ e = q_peek(&mq->clean, mq->clean.nr_levels / 2, true);
if (!e) {
- if (!clean_target_met(mq, false))
+ if (!clean_target_met(mq, true))
queue_writeback(mq);
return;
}
* We always claim to be 'idle' to ensure some demotions happen
* with continuous loads.
*/
- if (!free_target_met(mq, true))
+ if (!free_target_met(mq))
queue_demotion(mq);
return;
}
spin_lock_irqsave(&mq->lock, flags);
r = btracker_issue(mq->bg_work, result);
if (r == -ENODATA) {
- /* find some writeback work to do */
- if (mq->migrations_allowed && !free_target_met(mq, idle))
- queue_demotion(mq);
-
- else if (!clean_target_met(mq, idle))
+ if (!clean_target_met(mq, idle)) {
queue_writeback(mq);
-
- r = btracker_issue(mq->bg_work, result);
+ r = btracker_issue(mq->bg_work, result);
+ }
}
spin_unlock_irqrestore(&mq->lock, flags);
clear_pending(mq, e);
if (success) {
e->oblock = work->oblock;
+ e->level = NR_CACHE_LEVELS - 1;
push(mq, e);
// h, q, a
} else {
static void __iot_io_end(struct io_tracker *iot, sector_t len)
{
+ if (!len)
+ return;
+
iot->in_flight -= len;
if (!iot->in_flight)
iot->idle_time = jiffies;
spinlock_t invalidation_lock;
struct list_head invalidation_requests;
- struct io_tracker origin_tracker;
+ struct io_tracker tracker;
struct work_struct commit_ws;
struct batcher committer;
static bool accountable_bio(struct cache *cache, struct bio *bio)
{
- return ((bio->bi_bdev == cache->origin_dev->bdev) &&
- bio_op(bio) != REQ_OP_DISCARD);
+ return bio_op(bio) != REQ_OP_DISCARD;
}
static void accounted_begin(struct cache *cache, struct bio *bio)
if (accountable_bio(cache, bio)) {
pb->len = bio_sectors(bio);
- iot_io_begin(&cache->origin_tracker, pb->len);
+ iot_io_begin(&cache->tracker, pb->len);
}
}
size_t pb_data_size = get_per_bio_data_size(cache);
struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size);
- iot_io_end(&cache->origin_tracker, pb->len);
+ iot_io_end(&cache->tracker, pb->len);
}
static void accounted_request(struct cache *cache, struct bio *bio)
enum busy {
IDLE,
- MODERATE,
BUSY
};
static enum busy spare_migration_bandwidth(struct cache *cache)
{
- bool idle = iot_idle_for(&cache->origin_tracker, HZ);
+ bool idle = iot_idle_for(&cache->tracker, HZ);
sector_t current_volume = (atomic_read(&cache->nr_io_migrations) + 1) *
cache->sectors_per_block;
- if (current_volume <= cache->migration_threshold)
- return idle ? IDLE : MODERATE;
+ if (idle && current_volume <= cache->migration_threshold)
+ return IDLE;
else
- return idle ? MODERATE : BUSY;
+ return BUSY;
}
static void inc_hit_counter(struct cache *cache, struct bio *bio)
for (;;) {
b = spare_migration_bandwidth(cache);
- if (b == BUSY)
- break;
r = policy_get_background_work(cache->policy, b == IDLE, &op);
if (r == -ENODATA)
batcher_init(&cache->committer, commit_op, cache,
issue_op, cache, cache->wq);
- iot_init(&cache->origin_tracker);
+ iot_init(&cache->tracker);
init_rwsem(&cache->background_work_lock);
prevent_background_work(cache);
cancel_delayed_work(&cache->waker);
flush_workqueue(cache->wq);
- WARN_ON(cache->origin_tracker.in_flight);
+ WARN_ON(cache->tracker.in_flight);
/*
* If it's a flush suspend there won't be any deferred bios, so this
* it has been invoked.
*/
#define dm_report_EIO(m) \
-({ \
+do { \
struct mapped_device *md = dm_table_get_md((m)->ti->table); \
\
pr_debug("%s: returning EIO; QIFNP = %d; SQIFNP = %d; DNFS = %d\n", \
test_bit(MPATHF_QUEUE_IF_NO_PATH, &(m)->flags), \
test_bit(MPATHF_SAVED_QUEUE_IF_NO_PATH, &(m)->flags), \
dm_noflush_suspending((m)->ti)); \
- -EIO; \
-})
+} while (0)
/*
* Map cloned requests (request-based multipath)
if (!pgpath) {
if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
return DM_MAPIO_DELAY_REQUEUE;
- return dm_report_EIO(m); /* Failed */
+ dm_report_EIO(m); /* Failed */
+ return DM_MAPIO_KILL;
} else if (test_bit(MPATHF_QUEUE_IO, &m->flags) ||
test_bit(MPATHF_PG_INIT_REQUIRED, &m->flags)) {
if (pg_init_all_paths(m))
if (!pgpath) {
if (test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
return DM_MAPIO_REQUEUE;
- return dm_report_EIO(m);
+ dm_report_EIO(m);
+ return -EIO;
}
mpio->pgpath = pgpath;
if (atomic_read(&m->nr_valid_paths) == 0 &&
!test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
if (error == -EIO)
- error = dm_report_EIO(m);
+ dm_report_EIO(m);
/* complete with the original error */
r = DM_ENDIO_DONE;
}
fail_path(mpio->pgpath);
if (atomic_read(&m->nr_valid_paths) == 0 &&
- !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))
- return dm_report_EIO(m);
+ !test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags)) {
+ dm_report_EIO(m);
+ return -EIO;
+ }
/* Queue for the daemon to resubmit */
dm_bio_restore(get_bio_details_from_bio(clone), clone);
case DM_MAPIO_KILL:
/* The target wants to complete the I/O */
dm_kill_unmapped_request(rq, -EIO);
+ break;
default:
DMWARN("unimplemented target map return value: %d", r);
BUG();
if (r < 0)
return r;
- r = save_sm_roots(pmd);
+ r = dm_tm_pre_commit(pmd->tm);
if (r < 0)
return r;
- r = dm_tm_pre_commit(pmd->tm);
+ r = save_sm_roots(pmd);
if (r < 0)
return r;
static int sm_disk_dec_block(struct dm_space_map *sm, dm_block_t b)
{
+ int r;
+ uint32_t old_count;
enum allocation_event ev;
struct sm_disk *smd = container_of(sm, struct sm_disk, sm);
- return sm_ll_dec(&smd->ll, b, &ev);
+ r = sm_ll_dec(&smd->ll, b, &ev);
+ if (!r && (ev == SM_FREE)) {
+ /*
+ * It's only free if it's also free in the last
+ * transaction.
+ */
+ r = sm_ll_lookup(&smd->old_ll, b, &old_count);
+ if (!r && !old_count)
+ smd->nr_allocated_this_transaction--;
+ }
+
+ return r;
}
static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b)
*/
recalc_sigpending();
if (signal_pending(current)) {
- spin_unlock(¤t->sighand->siglock);
- write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
goto bad_fork_cancel_cgroup;
}
+ if (unlikely(!(ns_of_pid(pid)->nr_hashed & PIDNS_HASH_ADDING))) {
+ retval = -ENOMEM;
+ goto bad_fork_cancel_cgroup;
+ }
if (likely(p->pid)) {
ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
return p;
bad_fork_cancel_cgroup:
+ spin_unlock(¤t->sighand->siglock);
+ write_unlock_irq(&tasklist_lock);
cgroup_cancel_fork(p);
bad_fork_free_pid:
cgroup_threadgroup_change_end(current);
* if reparented.
*/
for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
+ set_current_state(TASK_INTERRUPTIBLE);
if (pid_ns->nr_hashed == init_pids)
break;
schedule();
#
# ==========================================================================
+PHONY := __headers
+__headers:
+
+include scripts/Kbuild.include
+
+srcdir := $(srctree)/$(obj)
+subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
+# caller may set destination dir (when installing to asm/)
+_dst := $(if $(dst),$(dst),$(obj))
+
+# Recursion
+__headers: $(subdirs)
+
+.PHONY: $(subdirs)
+$(subdirs):
+ $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
+
+# Skip header install/check for include/uapi and arch/$(hdr-arch)/include/uapi.
+# We have only sub-directories there.
+skip-inst := $(if $(filter %/uapi,$(obj)),1)
+
+ifeq ($(skip-inst),)
+
# generated header directory
gen := $(if $(gen),$(gen),$(subst include/,include/generated/,$(obj)))
kbuild-file := $(srctree)/$(obj)/Kbuild
-include $(kbuild-file)
-# called may set destination dir (when installing to asm/)
-_dst := $(if $(dst),$(dst),$(obj))
-
old-kbuild-file := $(srctree)/$(subst uapi/,,$(obj))/Kbuild
ifneq ($(wildcard $(old-kbuild-file)),)
include $(old-kbuild-file)
endif
-include scripts/Kbuild.include
-
installdir := $(INSTALL_HDR_PATH)/$(subst uapi/,,$(_dst))
-srcdir := $(srctree)/$(obj)
gendir := $(objtree)/$(gen)
-subdirs := $(patsubst $(srcdir)/%/.,%,$(wildcard $(srcdir)/*/.))
header-files := $(notdir $(wildcard $(srcdir)/*.h))
header-files += $(notdir $(wildcard $(srcdir)/*.agh))
header-files := $(filter-out $(no-export-headers), $(header-files))
$(PERL) $< $(INSTALL_HDR_PATH)/include $(SRCARCH); \
touch $@
-PHONY += __headersinst __headerscheck
-
ifndef HDRCHECK
# Rules for installing headers
-__headersinst: $(subdirs) $(install-file)
+__headers: $(install-file)
@:
targets += $(install-file)
$(call if_changed,install)
else
-__headerscheck: $(subdirs) $(check-file)
+__headers: $(check-file)
@:
targets += $(check-file)
endif
-# Recursion
-.PHONY: $(subdirs)
-$(subdirs):
- $(Q)$(MAKE) $(hdr-inst)=$(obj)/$@ dst=$(_dst)/$@
-
targets := $(wildcard $(sort $(targets)))
cmd_files := $(wildcard \
$(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
include $(cmd_files)
endif
+endif # skip-inst
+
.PHONY: $(PHONY)
PHONY += FORCE
FORCE: ;