/* * Initialize and return retrieve the jiffies update. */ static ktime_t tick_init_jiffy_update(void) { ktime_t period; raw_spin_lock(&xtime_lock); write_seqcount_begin(&xtime_seq); /* Did we start the jiffies update yet ? */ if (last_jiffies_update.tv64 == 0) last_jiffies_update = tick_next_period; period = last_jiffies_update; write_seqcount_end(&xtime_seq); raw_spin_unlock(&xtime_lock); return period; }
/* * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. * It can block. */ void set_fs_root(struct fs_struct *fs, struct path *path) { struct path old_root; path_get_longterm(path); spin_lock(&fs->lock); write_seqcount_begin(&fs->seq); old_root = fs->root; fs->root = *path; write_seqcount_end(&fs->seq); spin_unlock(&fs->lock); if (old_root.dentry) path_put_longterm(&old_root); }
void psi_memstall_tick(struct task_struct *task, int cpu) { struct psi_group *group; void *iter = NULL; while ((group = iterate_groups(task, &iter))) { struct psi_group_cpu *groupc; groupc = per_cpu_ptr(group->pcpu, cpu); write_seqcount_begin(&groupc->seq); record_times(groupc, cpu, true); write_seqcount_end(&groupc->seq); } }
/* * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. * It can block. */ void set_fs_pwd(struct fs_struct *fs, struct path *path) { struct path old_pwd; spin_lock(&fs->lock); write_seqcount_begin(&fs->seq); old_pwd = fs->pwd; fs->pwd = *path; path_get_longterm(path); write_seqcount_end(&fs->seq); spin_unlock(&fs->lock); if (old_pwd.dentry) path_put_longterm(&old_pwd); }
/* * Periodic tick */ static void tick_periodic(int cpu) { if (tick_do_timer_cpu == cpu) { raw_spin_lock(&xtime_lock); write_seqcount_begin(&xtime_seq); /* Keep track of the next tick event */ tick_next_period = ktime_add(tick_next_period, tick_period); do_timer(1); write_seqcount_end(&xtime_seq); raw_spin_unlock(&xtime_lock); } update_process_times(user_mode(get_irq_regs())); profile_tick(CPU_PROFILING); }
static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv, struct nft_regs *regs, const struct nft_pktinfo *pkt) { struct nft_counter *this_cpu; seqcount_t *myseq; local_bh_disable(); this_cpu = this_cpu_ptr(priv->counter); myseq = this_cpu_ptr(&nft_counter_seq); write_seqcount_begin(myseq); this_cpu->bytes += pkt->skb->len; this_cpu->packets++; write_seqcount_end(myseq); local_bh_enable(); }
/* * Must be called with interrupts disabled ! */ static void tick_do_update_jiffies64(ktime_t now) { unsigned long ticks = 0; ktime_t delta; /* * Do a quick check without holding xtime_lock: */ delta = ktime_sub(now, last_jiffies_update); if (delta.tv64 < tick_period.tv64) return; /* Reevalute with xtime_lock held */ raw_spin_lock(&xtime_lock); write_seqcount_begin(&xtime_seq); delta = ktime_sub(now, last_jiffies_update); if (delta.tv64 >= tick_period.tv64) { delta = ktime_sub(delta, tick_period); last_jiffies_update = ktime_add(last_jiffies_update, tick_period); /* Slow path for long timeouts */ if (unlikely(delta.tv64 >= tick_period.tv64)) { s64 incr = ktime_to_ns(tick_period); ticks = ktime_divns(delta, incr); last_jiffies_update = ktime_add_ns(last_jiffies_update, incr * ticks); } do_timer(++ticks); /* Keep the tick_next_period variable up to date */ tick_next_period = ktime_add(last_jiffies_update, tick_period); } write_seqcount_end(&xtime_seq); raw_spin_unlock(&xtime_lock); }
static void psi_group_change(struct psi_group *group, int cpu, unsigned int clear, unsigned int set) { struct psi_group_cpu *groupc; unsigned int t, m; groupc = per_cpu_ptr(group->pcpu, cpu); /* * First we assess the aggregate resource states this CPU's * tasks have been in since the last change, and account any * SOME and FULL time these may have resulted in. * * Then we update the task counts according to the state * change requested through the @clear and @set bits. */ write_seqcount_begin(&groupc->seq); record_times(groupc, cpu, false); for (t = 0, m = clear; m; m &= ~(1 << t), t++) { if (!(m & (1 << t))) continue; if (groupc->tasks[t] == 0 && !psi_bug) { printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u] clear=%x set=%x\n", cpu, t, groupc->tasks[0], groupc->tasks[1], groupc->tasks[2], clear, set); psi_bug = 1; } groupc->tasks[t]--; } for (t = 0; set; set &= ~(1 << t), t++) if (set & (1 << t)) groupc->tasks[t]++; write_seqcount_end(&groupc->seq); }
static void reservation_object_add_shared_inplace(struct reservation_object *obj, struct reservation_object_list *fobj, struct fence *fence) { u32 i; fence_get(fence); preempt_disable(); write_seqcount_begin(&obj->seq); for (i = 0; i < fobj->shared_count; ++i) { struct fence *old_fence; old_fence = rcu_dereference_protected(fobj->shared[i], reservation_object_held(obj)); if (old_fence->context == fence->context) { /* memory barrier is added by write_seqcount_begin */ RCU_INIT_POINTER(fobj->shared[i], fence); write_seqcount_end(&obj->seq); preempt_enable(); fence_put(old_fence); return; } } /* * memory barrier is added by write_seqcount_begin, * fobj->shared_count is protected by this lock too */ RCU_INIT_POINTER(fobj->shared[fobj->shared_count], fence); fobj->shared_count++; write_seqcount_end(&obj->seq); preempt_enable(); }