diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/bio.h | 6 | ||||
| -rw-r--r-- | include/linux/bpf_verifier.h | 3 | ||||
| -rw-r--r-- | include/linux/bsg-lib.h | 3 | ||||
| -rw-r--r-- | include/linux/compiler_attributes.h | 12 | ||||
| -rw-r--r-- | include/linux/dcache.h | 3 | ||||
| -rw-r--r-- | include/linux/dma-buf-io.h | 20 | ||||
| -rw-r--r-- | include/linux/futex.h | 19 | ||||
| -rw-r--r-- | include/linux/futex_types.h | 2 | ||||
| -rw-r--r-- | include/linux/greybus/bundle.h | 12 | ||||
| -rw-r--r-- | include/linux/irq-entry-common.h | 23 | ||||
| -rw-r--r-- | include/linux/kvm_host.h | 24 | ||||
| -rw-r--r-- | include/linux/overflow.h | 2 | ||||
| -rw-r--r-- | include/linux/pci.h | 12 | ||||
| -rw-r--r-- | include/linux/rbtree_augmented.h | 201 | ||||
| -rw-r--r-- | include/linux/rcutree.h | 2 | ||||
| -rw-r--r-- | include/linux/seq_file.h | 13 | ||||
| -rw-r--r-- | include/linux/serial_8250.h | 8 | ||||
| -rw-r--r-- | include/linux/spmi.h | 17 | ||||
| -rw-r--r-- | include/linux/usb/serial.h | 8 |
19 files changed, 278 insertions, 112 deletions
diff --git a/include/linux/bio.h b/include/linux/bio.h index 47aef63dba3b..7a794ce723b8 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -261,12 +261,6 @@ static inline struct folio *bio_first_folio_all(struct bio *bio) return page_folio(bio_first_page_all(bio)); } -static inline struct bio_vec *bio_last_bvec_all(struct bio *bio) -{ - WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)); - return &bio->bi_io_vec[bio->bi_vcnt - 1]; -} - /** * struct folio_iter - State for iterating all folios in a bio. * @folio: The current folio we're iterating. NULL after the last folio. diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 54cb6d3d0653..791398e14962 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -708,9 +708,6 @@ struct bpf_loop_exit { int to; /* instruction outside the loop */ }; -/* SCEV/widening register space: r0..r10 plus every stack slot of a frame. */ -#define BPF_SCEV_REGS_NUM (MAX_BPF_REG + MAX_BPF_STACK_SLOTS) - struct bpf_loop { struct bpf_backedge backedges[MAX_BACKEDGES]; /* edges exiting from this loop, includes edges from nested loops */ diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h index 14fa93268630..a697246feeac 100644 --- a/include/linux/bsg-lib.h +++ b/include/linux/bsg-lib.h @@ -66,7 +66,8 @@ void bsg_job_done(struct bsg_job *job, int result, unsigned int reply_payload_rcv_len); struct request_queue *bsg_setup_queue(struct device *dev, const char *name, struct queue_limits *lim, bsg_job_fn *job_fn, - bsg_timeout_fn *timeout, int dd_job_size); + bsg_timeout_fn *timeout, int dd_job_size, + unsigned int reply_len); void bsg_remove_queue(struct request_queue *q); void bsg_job_put(struct bsg_job *job); int __must_check bsg_job_get(struct bsg_job *job); diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index 476c4c560d17..625e95e684c7 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -323,6 +323,18 @@ #define __pure __attribute__((__pure__)) /* + * Optional: not supported by gcc + * Optional: only supported since clang >= 20.0 + * + * clang: https://clang.llvm.org/docs/AttributeReference.html#require-explicit-initialization + */ +#if __has_attribute(__require_explicit_initialization__) +# define __require_explicit_initialization __attribute__((__require_explicit_initialization__)) +#else +# define __require_explicit_initialization +#endif + +/* * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute * clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate diff --git a/include/linux/dcache.h b/include/linux/dcache.h index adf239f8205f..d5ce9ecb28f3 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -239,7 +239,8 @@ enum dentry_flags { DCACHE_DENTRY_CURSOR = BIT(25), DCACHE_NORCU = BIT(26), /* No RCU delay for freeing */ DCACHE_PERSISTENT = BIT(27), -/* 28, 29, 30 free */ + DCACHE_UNCOVERED = BIT(28), /* lost its mounts on its way out */ +/* 29, 30 free */ DCACHE_PRIVATE = BIT(31) /* fs-specific flag */ }; diff --git a/include/linux/dma-buf-io.h b/include/linux/dma-buf-io.h index 8ac338df51ff..b9bbeca1744f 100644 --- a/include/linux/dma-buf-io.h +++ b/include/linux/dma-buf-io.h @@ -74,6 +74,19 @@ __dma_buf_io_get_map(struct dma_buf_io_ctx *ctx) return map; } +/** + * dma_buf_io_get_map - Create a new or reference an existing map. + * @ctx: [in] dma-buf I/O context + * @nowait: [in] specifies whether it's allowed to block + * + * Create a new or acquire an existing map. When succeeds, it returns + * a referenced map, which should eventually be put down with + * dma_buf_io_map_drop(). If @nowait is set and the function would block, + * it return -EAGAIN, and the caller is expected to retry from a context + * where blocking is allowed. + * + * Returns a map on success, or ERR_PTR encoded errno otherwise. + */ static inline struct dma_buf_io_map * dma_buf_io_get_map(struct dma_buf_io_ctx *ctx, bool nowait) { @@ -88,6 +101,13 @@ dma_buf_io_get_map(struct dma_buf_io_ctx *ctx, bool nowait) return dma_buf_io_create_map(ctx); } +/** + * dma_buf_io_map_drop - Drop the map. + * @map: [in] dma-buf I/O map + * + * Put down a reference for the @map acquired via dma_buf_io_get_map(). + * Should be called as soon as I/O is completed. + */ static inline void dma_buf_io_map_drop(struct dma_buf_io_map *map) { percpu_ref_put(&map->refs); diff --git a/include/linux/futex.h b/include/linux/futex.h index 18ed18d5cbc1..a895d8c69d66 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -23,28 +23,32 @@ struct task_struct; * 01 : Shared futex (PTHREAD_PROCESS_SHARED) * mapped on a file (reference on the underlying inode) * 10 : Shared futex (PTHREAD_PROCESS_SHARED) - * (but private mapping on an mm, and reference taken on it) + * (but private mapping on an mm) */ -#define FUT_OFF_INODE 1 /* We set bit 0 if key has a reference on inode */ -#define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */ +#define FUT_OFF_INODE 1 /* We set bit 0 if shared key identifies an inode */ +#define FUT_OFF_MMSHARED 2 /* We set bit 1 if shared key identifies an mm */ union futex_key { + /* For FUT_OFF_INODE */ struct { u64 i_seq; unsigned long pgoff; unsigned int offset; /* unsigned int node; */ } shared; + + /* For FUT_OFF_MMSHARED or private */ struct { union { - struct mm_struct *mm; - u64 __tmp; + struct mm_struct *mm; /* for private */ + u64 mm_seq; /* for FUT_OFF_MMSHARED */ }; unsigned long address; unsigned int offset; /* unsigned int node; */ } private; + struct { u64 ptr; unsigned long word; @@ -152,11 +156,10 @@ static inline void futex_set_vdso_cs_range(struct futex_mm_data *fd, unsigned in static inline void futex_fixup_robust_unlock(struct pt_regs *regs) { } #endif /* !CONFIG_FUTEX_ROBUST_UNLOCK */ - -#if defined(CONFIG_FUTEX_PRIVATE_HASH) || defined(CONFIG_FUTEX_ROBUST_UNLOCK) +#ifdef CONFIG_FUTEX void futex_mm_init(struct mm_struct *mm); #else static inline void futex_mm_init(struct mm_struct *mm) { } -#endif +#endif /* !CONFIG_FUTEX */ #endif /* _LINUX_FUTEX_H */ diff --git a/include/linux/futex_types.h b/include/linux/futex_types.h index d320c0571f0c..34b16f2828e7 100644 --- a/include/linux/futex_types.h +++ b/include/linux/futex_types.h @@ -85,10 +85,12 @@ struct futex_unlock_cs_ranges { }; * struct futex_mm_data - Futex related per MM data * @phash: Futex private hash related data * @unlock: Futex unlock VDSO critical sections + * @unique_id: Unique ID of the MM, for FUT_OFF_MMSHARED futexes */ struct futex_mm_data { struct futex_mm_phash phash; struct futex_unlock_cs_ranges unlock; + atomic64_t unique_id; }; #else /* CONFIG_FUTEX */ struct futex_sched_data { }; diff --git a/include/linux/greybus/bundle.h b/include/linux/greybus/bundle.h index df8d88424cb7..361a94d3499b 100644 --- a/include/linux/greybus/bundle.h +++ b/include/linux/greybus/bundle.h @@ -59,14 +59,9 @@ static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle) return 0; } -static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) +static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) { - int retval; - - pm_runtime_mark_last_busy(&bundle->dev); - retval = pm_runtime_put_autosuspend(&bundle->dev); - - return retval; + pm_runtime_put_autosuspend(&bundle->dev); } static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) @@ -82,8 +77,7 @@ static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) #else static inline int gb_pm_runtime_get_sync(struct gb_bundle *bundle) { return 0; } -static inline int gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) -{ return 0; } +static inline void gb_pm_runtime_put_autosuspend(struct gb_bundle *bundle) {} static inline void gb_pm_runtime_get_noresume(struct gb_bundle *bundle) {} static inline void gb_pm_runtime_put_noidle(struct gb_bundle *bundle) {} diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h index 2be273bb68f0..d5a66f54d70b 100644 --- a/include/linux/irq-entry-common.h +++ b/include/linux/irq-entry-common.h @@ -453,6 +453,25 @@ static inline void irqentry_exit_to_kernel_mode_preempt(struct pt_regs *regs, irqentry_exit_cond_resched(); } +/* + * The deferred hrtimer rearm is the tail of the timer interrupt, moved to the + * interrupt return path so that it runs after a possible reschedule. By now + * irq_exit_rcu() has left lockdep's hardirq context. Re-enter it for the + * rearm, so that the hrtimer base lock and the timekeeping sequence count are + * not chained onto the locks held by the interrupted context, which would add + * new lock chains for every lock stack an interrupt hits. + * + * The rearm on return to user mode needs no such annotation: no locks are + * held there, so it uses the same lock chains as the rearm in hardirq + * context. + */ +static __always_inline void irqentry_hrtimer_rearm_deferred(void) +{ + lockdep_hardirq_enter(); + hrtimer_rearm_deferred(); + lockdep_hardirq_exit(); +} + /** * irqentry_exit_to_kernel_mode_after_preempt - Establish trace, lockdep and RCU state * @regs: Pointer to current's pt_regs @@ -476,7 +495,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_ */ if (state.exit_rcu) { instrumentation_begin(); - hrtimer_rearm_deferred(); + irqentry_hrtimer_rearm_deferred(); /* Tell the tracer that IRET will enable interrupts */ trace_hardirqs_on_prepare(); lockdep_hardirqs_on_prepare(); @@ -487,7 +506,7 @@ irqentry_exit_to_kernel_mode_after_preempt(struct pt_regs *regs, irqentry_state_ } instrumentation_begin(); - hrtimer_rearm_deferred(); + irqentry_hrtimer_rearm_deferred(); /* Covers both tracing and lockdep */ trace_hardirqs_on(); instrumentation_end(); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f6e6a6c7b18c..4d4e76a50d77 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -45,6 +45,10 @@ #include <asm/kvm_host.h> #include <linux/kvm_dirty_ring.h> +#define __KVM_DEV_STRING(name, x) __stringify(name ## _ ## x) +#define _KVM_DEV_STRING(name, x) __KVM_DEV_STRING(name, x) +#define KVM_DEV_STRING(x) _KVM_DEV_STRING(KVM_DEV_NAME, x) + #ifndef KVM_MAX_VCPU_IDS #define KVM_MAX_VCPU_IDS KVM_MAX_VCPUS #endif @@ -725,7 +729,11 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu) #ifndef kvm_arch_has_readonly_mem static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) { - return IS_ENABLED(CONFIG_HAVE_KVM_READONLY_MEM); +#ifdef __KVM_HAVE_READONLY_MEM + return true; +#else + return false; +#endif } #endif @@ -817,7 +825,7 @@ struct kvm { struct kvm_vm_stat stat; struct kvm_arch arch; refcount_t users_count; -#ifdef CONFIG_KVM_MMIO +#ifndef __KVM_NO_MMIO struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; spinlock_t ring_lock; struct list_head coalesced_zones; @@ -2462,7 +2470,7 @@ void kvm_arch_update_irqfd_routing(struct kvm_kernel_irqfd *irqfd, struct kvm_kernel_irq_routing_entry *new); #endif /* CONFIG_HAVE_KVM_IRQ_BYPASS */ -#ifdef CONFIG_HAVE_KVM_INVALID_WAKEUPS +#ifdef __KVM_HAVE_INVALID_WAKEUPS /* If we wakeup during the poll time, was it a sucessful poll? */ static inline bool vcpu_valid_wakeup(struct kvm_vcpu *vcpu) { @@ -2474,9 +2482,9 @@ static inline bool vcpu_valid_wakeup(struct kvm_vcpu *vcpu) { return true; } -#endif /* CONFIG_HAVE_KVM_INVALID_WAKEUPS */ +#endif /* __KVM_HAVE_INVALID_WAKEUPS */ -#ifdef CONFIG_HAVE_KVM_NO_POLL +#ifdef __KVM_HAVE_NO_POLL /* Callback that tells if we must not poll */ bool kvm_arch_no_poll(struct kvm_vcpu *vcpu); #else @@ -2484,18 +2492,18 @@ static inline bool kvm_arch_no_poll(struct kvm_vcpu *vcpu) { return false; } -#endif /* CONFIG_HAVE_KVM_NO_POLL */ +#endif /* __KVM_HAVE_NO_POLL */ void kvm_arch_guest_memory_reclaimed(struct kvm *kvm); -#ifdef CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE +#ifdef __KVM_HAVE_VCPU_RUN_PID_CHANGE int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu); #else static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) { return 0; } -#endif /* CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE */ +#endif /* __KVM_HAVE_VCPU_RUN_PID_CHANGE */ #ifdef CONFIG_VIRT_XFER_TO_GUEST_WORK static inline void kvm_handle_signal_exit(struct kvm_vcpu *vcpu) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index a8cb6319b4fb..d0f04436343e 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -418,7 +418,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr #define flex_array_size(p, member, count) \ __builtin_choose_expr(__is_constexpr(count), \ (count) * sizeof(*(p)->member) + __must_be_array((p)->member), \ - size_mul(count, sizeof(*(p)->member) + __must_be_array((p)->member))) + size_mul(count, sizeof(*(p)->member)) + __must_be_array((p)->member)) /** * struct_size() - Calculate size of structure with trailing flexible array. diff --git a/include/linux/pci.h b/include/linux/pci.h index 79b1a0f0f861..6482549a8417 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -616,7 +616,10 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev) struct pci_dev *pci_alloc_dev(struct pci_bus *bus); -#define to_pci_dev(n) container_of(n, struct pci_dev, dev) +static inline struct pci_dev *to_pci_dev(const struct device *dev) +{ + return container_of(dev, struct pci_dev, dev); +} #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) #define for_each_pci_dev_reverse(d) \ while ((d = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) @@ -1961,10 +1964,9 @@ int pci_disable_link_state(struct pci_dev *pdev, int state); int pci_disable_link_state_locked(struct pci_dev *pdev, int state); int pci_enable_link_state(struct pci_dev *pdev, int state); int pci_enable_link_state_locked(struct pci_dev *pdev, int state); -int pci_force_enable_link_state(struct pci_dev *pdev, int state); void pcie_no_aspm(void); bool pcie_aspm_support_enabled(void); -u32 pcie_aspm_enabled(struct pci_dev *pdev); +bool pcie_aspm_enabled(struct pci_dev *pdev); #else static inline int pci_disable_link_state(struct pci_dev *pdev, int state) { return 0; } @@ -1974,11 +1976,9 @@ static inline int pci_enable_link_state(struct pci_dev *pdev, int state) { return 0; } static inline int pci_enable_link_state_locked(struct pci_dev *pdev, int state) { return 0; } -static inline int pci_force_enable_link_state(struct pci_dev *pdev, int state) -{ return 0; } static inline void pcie_no_aspm(void) { } static inline bool pcie_aspm_support_enabled(void) { return false; } -static inline u32 pcie_aspm_enabled(struct pci_dev *pdev) { return 0; } +static inline bool pcie_aspm_enabled(struct pci_dev *pdev) { return false; } #endif #ifdef CONFIG_HOTPLUG_PCI diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h index d2fa1c41bfd2..b9fc1be86ae3 100644 --- a/include/linux/rbtree_augmented.h +++ b/include/linux/rbtree_augmented.h @@ -15,6 +15,8 @@ #include <linux/compiler.h> #include <linux/rbtree.h> #include <linux/rcupdate.h> +#include <linux/args.h> +#include <linux/minmax.h> /* * Please note - only struct rb_augment_callbacks and the prototypes for @@ -28,6 +30,7 @@ struct rb_augment_callbacks { void (*propagate)(struct rb_node *node, struct rb_node *stop); void (*copy)(struct rb_node *old, struct rb_node *new); void (*rotate)(struct rb_node *old, struct rb_node *new); + void (*merge)(struct rb_node *node, struct rb_node *new); }; extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, @@ -60,6 +63,12 @@ rb_insert_augmented_cached(struct rb_node *node, rb_insert_augmented(node, &root->rb_root, augment); } +/* + * Insert @node into the leftmost cached augmented tree @tree. + * + * The augmented data of @node must already describe @node alone; it is + * merged into every ancestor on the way down through augment->merge(). + */ static __always_inline struct rb_node * rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree, bool (*less)(struct rb_node *, const struct rb_node *), @@ -71,6 +80,7 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree, while (*link) { parent = *link; + augment->merge(parent, node); if (less(node, parent)) { link = &parent->rb_left; } else { @@ -80,12 +90,108 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree, } rb_link_node(node, parent, link); - augment->propagate(parent, NULL); /* suboptimal */ rb_insert_augmented_cached(node, tree, leftmost, augment); return leftmost ? node : NULL; } +#define RB_FOR_EACH_1(what, RBNAME, RBSTRUCT, RBFIELD, x) \ + what(1, RBNAME, RBSTRUCT, RBFIELD, x) + +#define RB_FOR_EACH_2(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(2, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_1(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH_3(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(3, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_2(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH_4(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(4, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_3(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH_5(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(5, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_4(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH_6(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(6, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_5(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH_7(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(7, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_6(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH_8(what, RBNAME, RBSTRUCT, RBFIELD, x, ...) \ + what(8, RBNAME, RBSTRUCT, RBFIELD, x) \ + RB_FOR_EACH_7(what, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +#define RB_FOR_EACH(action, RBNAME, RBSTRUCT, RBFIELD, ...) \ + CONCATENATE(RB_FOR_EACH_, COUNT_ARGS(__VA_ARGS__)) \ + (action, RBNAME, RBSTRUCT, RBFIELD, __VA_ARGS__) + +/* + * One augmented field: @val is the node's own contribution (a member for + * RB_AUG(), a function of the node for RB_AUG_FUNC()), @aug the member + * holding the aggregate over the subtree, and @fold(a, b) combines two + * aggregates: min, max, a sum, ... It must be commutative and associative. + */ +#define RB_AUG_FUNC(val, aug, fold) (val(s), aug, fold) +#define RB_AUG(val, aug, fold) (s->val, aug, fold) +#define RB_UNPACK(...) __VA_ARGS__ + +#define __RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \ +static inline void \ +RBNAME ## _copy_ ## n(RBSTRUCT *old, RBSTRUCT *new) \ +{ \ + new->aug = old->aug; \ +} \ +static inline bool \ +RBNAME ## _compute_ ## n(RBSTRUCT *s, bool exit) \ +{ \ + TYPEOF_UNQUAL(s->aug) _old_aug = s->aug; \ + TYPEOF_UNQUAL(s->aug) _val = val; \ + struct rb_node *_node = &s->RBFIELD; \ + if (_node->rb_right) { \ + RBSTRUCT *_c = container_of(_node->rb_right, typeof(*s), RBFIELD); \ + _val = fold(_val, _c->aug); \ + } \ + if (_node->rb_left) { \ + RBSTRUCT *_c = container_of(_node->rb_left, typeof(*s), RBFIELD); \ + _val = fold(_val, _c->aug); \ + } \ + if (exit && _old_aug == _val) \ + return true; \ + s->aug = _val; \ + return false; \ +} +#define _RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, args) \ + __RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, args) +#define RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, x) \ + _RB_INST(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x) + +#define __RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \ + RBNAME ## _copy_ ## n(old, new); +#define _RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, args) \ + __RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, args) +#define RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, x) \ + _RB_COPY(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x) + +#define __RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \ + ret &= RBNAME ## _compute_ ## n(node, exit); +#define _RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, args) \ + __RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, args) +#define RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, x) \ + _RB_COMPUTE(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x) + +/* fold @new, about to become a descendant of @node, into @node */ +#define __RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, val, aug, fold) \ + node->aug = fold(node->aug, new->aug); +#define _RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, args) \ + __RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, args) +#define RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, x) \ + _RB_MERGE(n, RBNAME, RBSTRUCT, RBFIELD, RB_UNPACK x) + /* * Template for declaring augmented rbtree callbacks (generic multi fields) * @@ -93,18 +199,29 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree, * RBNAME: name of the rb_augment_callbacks structure * RBSTRUCT: struct type of the tree nodes * RBFIELD: name of struct rb_node field within RBSTRUCT - * RBCOPY: name of function that copies the RBAUGMENTED datas - * RBCOMPUTE: name of function that recomputes the RBAUGMENTED datas + * RBAUG...: list of RB_AUG() describing the augmented data */ - -#define RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \ - RBSTRUCT, RBFIELD, RBCOPY, RBCOMPUTE) \ +#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ + RBSTRUCT, RBFIELD, RBAUG...) \ +RB_FOR_EACH(RB_INST, RBNAME, RBSTRUCT, RBFIELD, RBAUG) \ +static inline void \ +RBNAME ## __copy(RBSTRUCT *old, RBSTRUCT *new) \ +{ \ + RB_FOR_EACH(RB_COPY, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \ +} \ +static inline bool \ +RBNAME ## __compute(RBSTRUCT *node, bool exit) \ +{ \ + bool ret = true; \ + RB_FOR_EACH(RB_COMPUTE, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \ + return ret; \ +} \ static inline void \ RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \ { \ while (rb != stop) { \ RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ - if (RBCOMPUTE(node, true)) \ + if (RBNAME ## __compute(node, true)) \ break; \ rb = rb_parent(&node->RBFIELD); \ } \ @@ -114,44 +231,31 @@ RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ { \ RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ - RBCOPY(new, old); \ + RBNAME ## __copy(old, new); \ } \ static void \ RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ { \ RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ - RBCOPY(new, old); \ - RBCOMPUTE(old, false); \ + RBNAME ## __copy(old, new); \ + RBNAME ## __compute(old, false); \ +} \ +static inline void \ +RBNAME ## _merge(struct rb_node *rb, struct rb_node *rb_new) \ +{ \ + RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ + RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ + RB_FOR_EACH(RB_MERGE, RBNAME, RBSTRUCT, RBFIELD, RBAUG); \ } \ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ .propagate = RBNAME ## _propagate, \ .copy = RBNAME ## _copy, \ - .rotate = RBNAME ## _rotate \ + .rotate = RBNAME ## _rotate, \ + .merge = RBNAME ## _merge \ }; /* - * Template for declaring augmented rbtree callbacks (generic single field) - * - * RBSTATIC: 'static' or empty - * RBNAME: name of the rb_augment_callbacks structure - * RBSTRUCT: struct type of the tree nodes - * RBFIELD: name of struct rb_node field within RBSTRUCT - * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree - * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data - */ - -#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ - RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \ -static inline void \ -RBNAME ## _copy_single(RBSTRUCT *new, RBSTRUCT *old) \ -{ \ - new->RBAUGMENTED = old->RBAUGMENTED; \ -} \ -RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \ - RBSTRUCT, RBFIELD, RBNAME ## _copy_single, RBCOMPUTE) - -/* * Template for declaring augmented rbtree callbacks, * computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes. * @@ -159,34 +263,15 @@ RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \ * RBNAME: name of the rb_augment_callbacks structure * RBSTRUCT: struct type of the tree nodes * RBFIELD: name of struct rb_node field within RBSTRUCT - * RBTYPE: type of the RBAUGMENTED field - * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree - * RBCOMPUTE: name of function that returns the per-node RBTYPE scalar + * RBTYPE: type of the RBAUGMENTED field -- unused, assumed typeof(RBAUGMENTED) + * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree + * RBVALUE: name of function that returns the per-node RBTYPE scalar */ -#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ - RBTYPE, RBAUGMENTED, RBCOMPUTE) \ -static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \ -{ \ - RBSTRUCT *child; \ - RBTYPE max = RBCOMPUTE(node); \ - if (node->RBFIELD.rb_left) { \ - child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \ - if (child->RBAUGMENTED > max) \ - max = child->RBAUGMENTED; \ - } \ - if (node->RBFIELD.rb_right) { \ - child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \ - if (child->RBAUGMENTED > max) \ - max = child->RBAUGMENTED; \ - } \ - if (exit && node->RBAUGMENTED == max) \ - return true; \ - node->RBAUGMENTED = max; \ - return false; \ -} \ -RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ - RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max) +#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBVALUE) \ +RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RB_AUG_FUNC(RBVALUE, RBAUGMENTED, max)) #define RB_RED 0 diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h index 16a04202888b..e6ad4f2a475c 100644 --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -116,7 +116,7 @@ int rcutree_offline_cpu(unsigned int cpu); void rcutree_migrate_callbacks(int cpu); -/* Called from hotplug and also arm64 early secondary boot failure */ +/* Called from hotplug */ void rcutree_report_cpu_dead(void); #endif /* __LINUX_RCUTREE_H */ diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index dc0e8c62d9e0..f0e7e52a0905 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -28,11 +28,16 @@ struct seq_file { void *private; }; +/* All four are called without checking for NULL. */ struct seq_operations { - void * (*start) (struct seq_file *m, loff_t *pos); - void (*stop) (struct seq_file *m, void *v); - void * (*next) (struct seq_file *m, void *v, loff_t *pos); - int (*show) (struct seq_file *m, void *v); + void *(*start)(struct seq_file *m, loff_t *pos) + __require_explicit_initialization; + void (*stop)(struct seq_file *m, void *v) + __require_explicit_initialization; + void *(*next)(struct seq_file *m, void *v, loff_t *pos) + __require_explicit_initialization; + int (*show)(struct seq_file *m, void *v) + __require_explicit_initialization; }; #define SEQ_SKIP 1 diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index eeb868e93e15..d91c0477be9d 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -186,10 +186,10 @@ static inline struct uart_8250_port *up_to_u8250p(struct uart_port *up) return container_of(up, struct uart_8250_port, port); } -int serial8250_register_8250_port(const struct uart_8250_port *); -void serial8250_unregister_port(int line); -void serial8250_suspend_port(int line); -void serial8250_resume_port(int line); +struct uart_8250_port *serial8250_register_8250_port(const struct uart_8250_port *); +void serial8250_unregister_port(struct uart_8250_port *); +void serial8250_suspend_port(struct uart_8250_port *); +void serial8250_resume_port(struct uart_8250_port *); int early_serial_setup(struct uart_port *port); int early_serial8250_setup(struct earlycon_device *device, const char *options); diff --git a/include/linux/spmi.h b/include/linux/spmi.h index 4eb9564a7fb3..4daebc980501 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -70,6 +70,22 @@ int spmi_device_add(struct spmi_device *sdev); void spmi_device_remove(struct spmi_device *sdev); /** + * struct spmi_subdevice - Basic representation of an SPMI sub-device + * @sdev: Sub-device representation of an SPMI device + * @devid: Platform Device ID of an SPMI sub-device + */ +struct spmi_subdevice { + struct spmi_device sdev; + unsigned int devid; +}; + +struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sparent); +void spmi_subdevice_remove(struct spmi_subdevice *sdev); + +struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *dev, + struct spmi_device *sparent); + +/** * struct spmi_controller - interface to the SPMI master controller * @dev: Driver model representation of the device. * @nr: board-specific number identifier for this controller/bus @@ -173,6 +189,7 @@ static inline void spmi_driver_unregister(struct spmi_driver *sdrv) struct device_node; struct spmi_device *spmi_find_device_by_of_node(struct device_node *np); +struct spmi_device *spmi_get_parent_spmi_device(struct device *dev); int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf); int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf, size_t len); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index ab0a32a90629..5866f19d3c7b 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -305,9 +305,17 @@ struct usb_serial_driver { void (*write_bulk_callback)(struct urb *urb); /* Called by the generic read bulk callback */ void (*process_read_urb)(struct urb *urb); + /* + * Called with port->lock held before preparing another write URB. + * Drivers returning false must restart the generic write path when + * writes may proceed again. + */ + bool (*write_ready)(struct usb_serial_port *port); /* Called by the generic write implementation */ int (*prepare_write_buffer)(struct usb_serial_port *port, void *dest, size_t size); + /* Called with port->lock held to roll back a failed write submission */ + void (*write_rollback)(struct usb_serial_port *port, int count); }; #define to_usb_serial_driver(d) \ container_of(d, struct usb_serial_driver, driver) |
