Merge branch 'for-7.0' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-7.1 for both ASoC and general bug fixes to support testing.
Showing the changes to include/linux (12 of 403 files). Show all
Unified · Split
| @@ -810,6 +810,12 @@ struct damon_ctx { · 809 unmodified lines | |||
| 810 | struct damos_walk_control *walk_control; | 810 | struct damos_walk_control *walk_control; |
| 811 | struct mutex walk_control_lock; | 811 | struct mutex walk_control_lock; |
| 812 | 812 | ||
| 813 | /* | ||
| 814 | * indicate if this may be corrupted. Currentonly this is set only for | ||
| 815 | * damon_commit_ctx() failure. | ||
| 816 | */ | ||
| 817 | bool maybe_corrupted; | ||
| 818 | |||
| 813 | /* Working thread of the given DAMON context */ | 819 | /* Working thread of the given DAMON context */ |
| 814 | struct task_struct *kdamond; | 820 | struct task_struct *kdamond; |
| 815 | /* Protects @kdamond field access */ | 821 | /* Protects @kdamond field access */ |
| @@ -80,11 +80,18 @@ · 79 unmodified lines | |||
| 80 | #define DMA_ATTR_MMIO (1UL << 10) | 80 | #define DMA_ATTR_MMIO (1UL << 10) |
| 81 | 81 | ||
| 82 | /* | 82 | /* |
| 83 | * DMA_ATTR_CPU_CACHE_CLEAN: Indicates the CPU will not dirty any cacheline | 83 | * DMA_ATTR_DEBUGGING_IGNORE_CACHELINES: Indicates the CPU cache line can be |
| 84 | * overlapping this buffer while it is mapped for DMA. All mappings sharing | 84 | * overlapped. All mappings sharing a cacheline must have this attribute for |
| 85 | * a cacheline must have this attribute for this to be considered safe. | 85 | * this to be considered safe. |
| 86 | */ | 86 | */ |
| 87 | #define DMA_ATTR_CPU_CACHE_CLEAN (1UL << 11) | 87 | #define DMA_ATTR_DEBUGGING_IGNORE_CACHELINES (1UL << 11) |
| 88 | |||
| 89 | /* | ||
| 90 | * DMA_ATTR_REQUIRE_COHERENT: Indicates that DMA coherency is required. | ||
| 91 | * All mappings that carry this attribute can't work with SWIOTLB and cache | ||
| 92 | * flushing. | ||
| 93 | */ | ||
| 94 | #define DMA_ATTR_REQUIRE_COHERENT (1UL << 12) | ||
| 88 | 95 | ||
| 89 | /* | 96 | /* |
| 90 | * A dma_addr_t can hold any valid DMA or bus address for the platform. It can | 97 | * A dma_addr_t can hold any valid DMA or bus address for the platform. It can |
| @@ -248,8 +255,8 @@ static inline void *dma_alloc_attrs(struct device *dev, size_t size, · 157 unmodified lines | |||
| 248 | { | 255 | { |
| 249 | return NULL; | 256 | return NULL; |
| 250 | } | 257 | } |
| 251 | static void dma_free_attrs(struct device *dev, size_t size, void *cpu_addr, | 258 | static inline void dma_free_attrs(struct device *dev, size_t size, |
| 252 | dma_addr_t dma_handle, unsigned long attrs) | 259 | void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs) |
| 253 | { | 260 | { |
| 254 | } | 261 | } |
| 255 | static inline void *dmam_alloc_attrs(struct device *dev, size_t size, | 262 | static inline void *dmam_alloc_attrs(struct device *dev, size_t size, |
| @@ -338,5 +338,6 @@ struct super_block { · 337 unmodified lines | |||
| 338 | #define SB_I_NOUMASK 0x00001000 /* VFS does not apply umask */ | 338 | #define SB_I_NOUMASK 0x00001000 /* VFS does not apply umask */ |
| 339 | #define SB_I_NOIDMAP 0x00002000 /* No idmapped mounts on this superblock */ | 339 | #define SB_I_NOIDMAP 0x00002000 /* No idmapped mounts on this superblock */ |
| 340 | #define SB_I_ALLOW_HSM 0x00004000 /* Allow HSM events on this superblock */ | 340 | #define SB_I_ALLOW_HSM 0x00004000 /* Allow HSM events on this superblock */ |
| 341 | #define SB_I_NO_DATA_INTEGRITY 0x00008000 /* fs cannot guarantee data persistence on sync */ | ||
| 341 | 342 | ||
| 342 | #endif /* _LINUX_FS_SUPER_TYPES_H */ | 343 | #endif /* _LINUX_FS_SUPER_TYPES_H */ |
| @@ -363,6 +363,23 @@ static inline unsigned long softleaf_to_pfn(softleaf_t entry) · 362 unmodified lines | |||
| 363 | return swp_offset(entry) & SWP_PFN_MASK; | 363 | return swp_offset(entry) & SWP_PFN_MASK; |
| 364 | } | 364 | } |
| 365 | 365 | ||
| 366 | static inline void softleaf_migration_sync(softleaf_t entry, | ||
| 367 | struct folio *folio) | ||
| 368 | { | ||
| 369 | /* | ||
| 370 | * Ensure we do not race with split, which might alter tail pages into new | ||
| 371 | * folios and thus result in observing an unlocked folio. | ||
| 372 | * This matches the write barrier in __split_folio_to_order(). | ||
| 373 | */ | ||
| 374 | smp_rmb(); | ||
| 375 | |||
| 376 | /* | ||
| 377 | * Any use of migration entries may only occur while the | ||
| 378 | * corresponding page is locked | ||
| 379 | */ | ||
| 380 | VM_WARN_ON_ONCE(!folio_test_locked(folio)); | ||
| 381 | } | ||
| 382 | |||
| 366 | /** | 383 | /** |
| 367 | * softleaf_to_page() - Obtains struct page for PFN encoded within leaf entry. | 384 | * softleaf_to_page() - Obtains struct page for PFN encoded within leaf entry. |
| 368 | * @entry: Leaf entry, softleaf_has_pfn(@entry) must return true. | 385 | * @entry: Leaf entry, softleaf_has_pfn(@entry) must return true. |
| @@ -374,11 +391,8 @@ static inline struct page *softleaf_to_page(softleaf_t entry) · 5 unmodified lines | |||
| 374 | struct page *page = pfn_to_page(softleaf_to_pfn(entry)); | 391 | struct page *page = pfn_to_page(softleaf_to_pfn(entry)); |
| 375 | 392 | ||
| 376 | VM_WARN_ON_ONCE(!softleaf_has_pfn(entry)); | 393 | VM_WARN_ON_ONCE(!softleaf_has_pfn(entry)); |
| 377 | /* | 394 | if (softleaf_is_migration(entry)) |
| 378 | * Any use of migration entries may only occur while the | 395 | softleaf_migration_sync(entry, page_folio(page)); |
| 379 | * corresponding page is locked | ||
| 380 | */ | ||
| 381 | VM_WARN_ON_ONCE(softleaf_is_migration(entry) && !PageLocked(page)); | ||
| 382 | 396 | ||
| 383 | return page; | 397 | return page; |
| 384 | } | 398 | } |
| @@ -394,12 +408,8 @@ static inline struct folio *softleaf_to_folio(softleaf_t entry) · 9 unmodified lines | |||
| 394 | struct folio *folio = pfn_folio(softleaf_to_pfn(entry)); | 408 | struct folio *folio = pfn_folio(softleaf_to_pfn(entry)); |
| 395 | 409 | ||
| 396 | VM_WARN_ON_ONCE(!softleaf_has_pfn(entry)); | 410 | VM_WARN_ON_ONCE(!softleaf_has_pfn(entry)); |
| 397 | /* | 411 | if (softleaf_is_migration(entry)) |
| 398 | * Any use of migration entries may only occur while the | 412 | softleaf_migration_sync(entry, folio); |
| 399 | * corresponding folio is locked. | ||
| 400 | */ | ||
| 401 | VM_WARN_ON_ONCE(softleaf_is_migration(entry) && | ||
| 402 | !folio_test_locked(folio)); | ||
| 403 | 413 | ||
| 404 | return folio; | 414 | return folio; |
| 405 | } | 415 | } |
| @@ -55,6 +55,7 @@ struct mempolicy { · 54 unmodified lines | |||
| 55 | nodemask_t cpuset_mems_allowed; /* relative to these nodes */ | 55 | nodemask_t cpuset_mems_allowed; /* relative to these nodes */ |
| 56 | nodemask_t user_nodemask; /* nodemask passed by user */ | 56 | nodemask_t user_nodemask; /* nodemask passed by user */ |
| 57 | } w; | 57 | } w; |
| 58 | struct rcu_head rcu; | ||
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 60 | /* | 61 | /* |
| @@ -140,7 +140,6 @@ struct netfs_io_stream { · 139 unmodified lines | |||
| 140 | void (*issue_write)(struct netfs_io_subrequest *subreq); | 140 | void (*issue_write)(struct netfs_io_subrequest *subreq); |
| 141 | /* Collection tracking */ | 141 | /* Collection tracking */ |
| 142 | struct list_head subrequests; /* Contributory I/O operations */ | 142 | struct list_head subrequests; /* Contributory I/O operations */ |
| 143 | struct netfs_io_subrequest *front; /* Op being collected */ | ||
| 144 | unsigned long long collected_to; /* Position we've collected results to */ | 143 | unsigned long long collected_to; /* Position we've collected results to */ |
| 145 | size_t transferred; /* The amount transferred from this stream */ | 144 | size_t transferred; /* The amount transferred from this stream */ |
| 146 | unsigned short error; /* Aggregate error for the stream */ | 145 | unsigned short error; /* Aggregate error for the stream */ |
| @@ -210,7 +210,6 @@ enum mapping_flags { · 209 unmodified lines | |||
| 210 | AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM = 9, | 210 | AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM = 9, |
| 211 | AS_KERNEL_FILE = 10, /* mapping for a fake kernel file that shouldn't | 211 | AS_KERNEL_FILE = 10, /* mapping for a fake kernel file that shouldn't |
| 212 | account usage to user cgroups */ | 212 | account usage to user cgroups */ |
| 213 | AS_NO_DATA_INTEGRITY = 11, /* no data integrity guarantees */ | ||
| 214 | /* Bits 16-25 are used for FOLIO_ORDER */ | 213 | /* Bits 16-25 are used for FOLIO_ORDER */ |
| 215 | AS_FOLIO_ORDER_BITS = 5, | 214 | AS_FOLIO_ORDER_BITS = 5, |
| 216 | AS_FOLIO_ORDER_MIN = 16, | 215 | AS_FOLIO_ORDER_MIN = 16, |
| @@ -346,16 +345,6 @@ static inline bool mapping_writeback_may_deadlock_on_reclaim(const struct addres · 129 unmodified lines | |||
| 346 | return test_bit(AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM, &mapping->flags); | 345 | return test_bit(AS_WRITEBACK_MAY_DEADLOCK_ON_RECLAIM, &mapping->flags); |
| 347 | } | 346 | } |
| 348 | 347 | ||
| 349 | static inline void mapping_set_no_data_integrity(struct address_space *mapping) | ||
| 350 | { | ||
| 351 | set_bit(AS_NO_DATA_INTEGRITY, &mapping->flags); | ||
| 352 | } | ||
| 353 | |||
| 354 | static inline bool mapping_no_data_integrity(const struct address_space *mapping) | ||
| 355 | { | ||
| 356 | return test_bit(AS_NO_DATA_INTEGRITY, &mapping->flags); | ||
| 357 | } | ||
| 358 | |||
| 359 | static inline gfp_t mapping_gfp_mask(const struct address_space *mapping) | 348 | static inline gfp_t mapping_gfp_mask(const struct address_space *mapping) |
| 360 | { | 349 | { |
| 361 | return mapping->gfp_mask; | 350 | return mapping->gfp_mask; |
| @@ -145,6 +145,7 @@ enum lockdown_reason { · 144 unmodified lines | |||
| 145 | LOCKDOWN_BPF_WRITE_USER, | 145 | LOCKDOWN_BPF_WRITE_USER, |
| 146 | LOCKDOWN_DBG_WRITE_KERNEL, | 146 | LOCKDOWN_DBG_WRITE_KERNEL, |
| 147 | LOCKDOWN_RTAS_ERROR_INJECTION, | 147 | LOCKDOWN_RTAS_ERROR_INJECTION, |
| 148 | LOCKDOWN_XEN_USER_ACTIONS, | ||
| 148 | LOCKDOWN_INTEGRITY_MAX, | 149 | LOCKDOWN_INTEGRITY_MAX, |
| 149 | LOCKDOWN_KCORE, | 150 | LOCKDOWN_KCORE, |
| 150 | LOCKDOWN_KPROBES, | 151 | LOCKDOWN_KPROBES, |
| @@ -159,10 +159,6 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, · 158 unmodified lines | |||
| 159 | * @modalias: Name of the driver to use with this device, or an alias | 159 | * @modalias: Name of the driver to use with this device, or an alias |
| 160 | * for that name. This appears in the sysfs "modalias" attribute | 160 | * for that name. This appears in the sysfs "modalias" attribute |
| 161 | * for driver coldplugging, and in uevents used for hotplugging | 161 | * for driver coldplugging, and in uevents used for hotplugging |
| 162 | * @driver_override: If the name of a driver is written to this attribute, then | ||
| 163 | * the device will bind to the named driver and only the named driver. | ||
| 164 | * Do not set directly, because core frees it; use driver_set_override() to | ||
| 165 | * set or clear it. | ||
| 166 | * @pcpu_statistics: statistics for the spi_device | 162 | * @pcpu_statistics: statistics for the spi_device |
| 167 | * @word_delay: delay to be inserted between consecutive | 163 | * @word_delay: delay to be inserted between consecutive |
| 168 | * words of a transfer | 164 | * words of a transfer |
| @@ -224,7 +220,6 @@ struct spi_device { · 55 unmodified lines | |||
| 224 | void *controller_state; | 220 | void *controller_state; |
| 225 | void *controller_data; | 221 | void *controller_data; |
| 226 | char modalias[SPI_NAME_SIZE]; | 222 | char modalias[SPI_NAME_SIZE]; |
| 227 | const char *driver_override; | ||
| 228 | 223 | ||
| 229 | /* The statistics */ | 224 | /* The statistics */ |
| 230 | struct spi_statistics __percpu *pcpu_statistics; | 225 | struct spi_statistics __percpu *pcpu_statistics; |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #ifndef _LINUX_SRCU_TINY_H | 11 | #ifndef _LINUX_SRCU_TINY_H |
| 12 | #define _LINUX_SRCU_TINY_H | 12 | #define _LINUX_SRCU_TINY_H |
| 13 | 13 | ||
| 14 | #include <linux/irq_work_types.h> | ||
| 14 | #include <linux/swait.h> | 15 | #include <linux/swait.h> |
| 15 | 16 | ||
| 16 | struct srcu_struct { | 17 | struct srcu_struct { |
| @@ -24,18 +25,21 @@ struct srcu_struct { · 7 unmodified lines | |||
| 24 | struct rcu_head *srcu_cb_head; /* Pending callbacks: Head. */ | 25 | struct rcu_head *srcu_cb_head; /* Pending callbacks: Head. */ |
| 25 | struct rcu_head **srcu_cb_tail; /* Pending callbacks: Tail. */ | 26 | struct rcu_head **srcu_cb_tail; /* Pending callbacks: Tail. */ |
| 26 | struct work_struct srcu_work; /* For driving grace periods. */ | 27 | struct work_struct srcu_work; /* For driving grace periods. */ |
| 28 | struct irq_work srcu_irq_work; /* Defer schedule_work() to irq work. */ | ||
| 27 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 29 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
| 28 | struct lockdep_map dep_map; | 30 | struct lockdep_map dep_map; |
| 29 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ | 31 | #endif /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ |
| 30 | }; | 32 | }; |
| 31 | 33 | ||
| 32 | void srcu_drive_gp(struct work_struct *wp); | 34 | void srcu_drive_gp(struct work_struct *wp); |
| 35 | void srcu_tiny_irq_work(struct irq_work *irq_work); | ||
| 33 | 36 | ||
| 34 | #define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \ | 37 | #define __SRCU_STRUCT_INIT(name, __ignored, ___ignored, ____ignored) \ |
| 35 | { \ | 38 | { \ |
| 36 | .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \ | 39 | .srcu_wq = __SWAIT_QUEUE_HEAD_INITIALIZER(name.srcu_wq), \ |
| 37 | .srcu_cb_tail = &name.srcu_cb_head, \ | 40 | .srcu_cb_tail = &name.srcu_cb_head, \ |
| 38 | .srcu_work = __WORK_INITIALIZER(name.srcu_work, srcu_drive_gp), \ | 41 | .srcu_work = __WORK_INITIALIZER(name.srcu_work, srcu_drive_gp), \ |
| 42 | .srcu_irq_work = { .func = srcu_tiny_irq_work }, \ | ||
| 39 | __SRCU_DEP_MAP_INIT(name) \ | 43 | __SRCU_DEP_MAP_INIT(name) \ |
| 40 | } | 44 | } |
| 41 | 45 | ||
| @@ -34,7 +34,7 @@ struct srcu_data { · 33 unmodified lines | |||
| 34 | /* Values: SRCU_READ_FLAVOR_.* */ | 34 | /* Values: SRCU_READ_FLAVOR_.* */ |
| 35 | 35 | ||
| 36 | /* Update-side state. */ | 36 | /* Update-side state. */ |
| 37 | spinlock_t __private lock ____cacheline_internodealigned_in_smp; | 37 | raw_spinlock_t __private lock ____cacheline_internodealigned_in_smp; |
| 38 | struct rcu_segcblist srcu_cblist; /* List of callbacks.*/ | 38 | struct rcu_segcblist srcu_cblist; /* List of callbacks.*/ |
| 39 | unsigned long srcu_gp_seq_needed; /* Furthest future GP needed. */ | 39 | unsigned long srcu_gp_seq_needed; /* Furthest future GP needed. */ |
| 40 | unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */ | 40 | unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */ |
| @@ -55,7 +55,7 @@ struct srcu_data { · 14 unmodified lines | |||
| 55 | * Node in SRCU combining tree, similar in function to rcu_data. | 55 | * Node in SRCU combining tree, similar in function to rcu_data. |
| 56 | */ | 56 | */ |
| 57 | struct srcu_node { | 57 | struct srcu_node { |
| 58 | spinlock_t __private lock; | 58 | raw_spinlock_t __private lock; |
| 59 | unsigned long srcu_have_cbs[4]; /* GP seq for children having CBs, but only */ | 59 | unsigned long srcu_have_cbs[4]; /* GP seq for children having CBs, but only */ |
| 60 | /* if greater than ->srcu_gp_seq. */ | 60 | /* if greater than ->srcu_gp_seq. */ |
| 61 | unsigned long srcu_data_have_cbs[4]; /* Which srcu_data structs have CBs for given GP? */ | 61 | unsigned long srcu_data_have_cbs[4]; /* Which srcu_data structs have CBs for given GP? */ |
| @@ -74,7 +74,7 @@ struct srcu_usage { · 12 unmodified lines | |||
| 74 | /* First node at each level. */ | 74 | /* First node at each level. */ |
| 75 | int srcu_size_state; /* Small-to-big transition state. */ | 75 | int srcu_size_state; /* Small-to-big transition state. */ |
| 76 | struct mutex srcu_cb_mutex; /* Serialize CB preparation. */ | 76 | struct mutex srcu_cb_mutex; /* Serialize CB preparation. */ |
| 77 | spinlock_t __private lock; /* Protect counters and size state. */ | 77 | raw_spinlock_t __private lock; /* Protect counters and size state. */ |
| 78 | struct mutex srcu_gp_mutex; /* Serialize GP work. */ | 78 | struct mutex srcu_gp_mutex; /* Serialize GP work. */ |
| 79 | unsigned long srcu_gp_seq; /* Grace-period seq #. */ | 79 | unsigned long srcu_gp_seq; /* Grace-period seq #. */ |
| 80 | unsigned long srcu_gp_seq_needed; /* Latest gp_seq needed. */ | 80 | unsigned long srcu_gp_seq_needed; /* Latest gp_seq needed. */ |
| @@ -95,6 +95,7 @@ struct srcu_usage { · 14 unmodified lines | |||
| 95 | unsigned long reschedule_jiffies; | 95 | unsigned long reschedule_jiffies; |
| 96 | unsigned long reschedule_count; | 96 | unsigned long reschedule_count; |
| 97 | struct delayed_work work; | 97 | struct delayed_work work; |
| 98 | struct irq_work irq_work; | ||
| 98 | struct srcu_struct *srcu_ssp; | 99 | struct srcu_struct *srcu_ssp; |
| 99 | }; | 100 | }; |
| 100 | 101 | ||
| @@ -156,7 +157,7 @@ struct srcu_struct { · 55 unmodified lines | |||
| 156 | 157 | ||
| 157 | #define __SRCU_USAGE_INIT(name) \ | 158 | #define __SRCU_USAGE_INIT(name) \ |
| 158 | { \ | 159 | { \ |
| 159 | .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ | 160 | .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ |
| 160 | .srcu_gp_seq = SRCU_GP_SEQ_INITIAL_VAL, \ | 161 | .srcu_gp_seq = SRCU_GP_SEQ_INITIAL_VAL, \ |
| 161 | .srcu_gp_seq_needed = SRCU_GP_SEQ_INITIAL_VAL_WITH_STATE, \ | 162 | .srcu_gp_seq_needed = SRCU_GP_SEQ_INITIAL_VAL_WITH_STATE, \ |
| 162 | .srcu_gp_seq_needed_exp = SRCU_GP_SEQ_INITIAL_VAL, \ | 163 | .srcu_gp_seq_needed_exp = SRCU_GP_SEQ_INITIAL_VAL, \ |
| @@ -207,6 +207,39 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb, · 206 unmodified lines | |||
| 207 | return __virtio_net_hdr_to_skb(skb, hdr, little_endian, hdr->gso_type); | 207 | return __virtio_net_hdr_to_skb(skb, hdr, little_endian, hdr->gso_type); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | /* This function must be called after virtio_net_hdr_from_skb(). */ | ||
| 211 | static inline void __virtio_net_set_hdrlen(const struct sk_buff *skb, | ||
| 212 | struct virtio_net_hdr *hdr, | ||
| 213 | bool little_endian) | ||
| 214 | { | ||
| 215 | u16 hdr_len; | ||
| 216 | |||
| 217 | hdr_len = skb_transport_offset(skb); | ||
| 218 | |||
| 219 | if (hdr->gso_type == VIRTIO_NET_HDR_GSO_UDP_L4) | ||
| 220 | hdr_len += sizeof(struct udphdr); | ||
| 221 | else | ||
| 222 | hdr_len += tcp_hdrlen(skb); | ||
| 223 | |||
| 224 | hdr->hdr_len = __cpu_to_virtio16(little_endian, hdr_len); | ||
| 225 | } | ||
| 226 | |||
| 227 | /* This function must be called after virtio_net_hdr_from_skb(). */ | ||
| 228 | static inline void __virtio_net_set_tnl_hdrlen(const struct sk_buff *skb, | ||
| 229 | struct virtio_net_hdr *hdr) | ||
| 230 | { | ||
| 231 | u16 hdr_len; | ||
| 232 | |||
| 233 | hdr_len = skb_inner_transport_offset(skb); | ||
| 234 | |||
| 235 | if (hdr->gso_type == VIRTIO_NET_HDR_GSO_UDP_L4) | ||
| 236 | hdr_len += sizeof(struct udphdr); | ||
| 237 | else | ||
| 238 | hdr_len += inner_tcp_hdrlen(skb); | ||
| 239 | |||
| 240 | hdr->hdr_len = __cpu_to_virtio16(true, hdr_len); | ||
| 241 | } | ||
| 242 | |||
| 210 | static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb, | 243 | static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb, |
| 211 | struct virtio_net_hdr *hdr, | 244 | struct virtio_net_hdr *hdr, |
| 212 | bool little_endian, | 245 | bool little_endian, |
| @@ -385,7 +418,8 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb, · 172 unmodified lines | |||
| 385 | bool tnl_hdr_negotiated, | 418 | bool tnl_hdr_negotiated, |
| 386 | bool little_endian, | 419 | bool little_endian, |
| 387 | int vlan_hlen, | 420 | int vlan_hlen, |
| 388 | bool has_data_valid) | 421 | bool has_data_valid, |
| 422 | bool feature_hdrlen) | ||
| 389 | { | 423 | { |
| 390 | struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)vhdr; | 424 | struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)vhdr; |
| 391 | unsigned int inner_nh, outer_th; | 425 | unsigned int inner_nh, outer_th; |
| @@ -394,9 +428,17 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb, · 2 unmodified lines | |||
| 394 | 428 | ||
| 395 | tnl_gso_type = skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | | 429 | tnl_gso_type = skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL | |
| 396 | SKB_GSO_UDP_TUNNEL_CSUM); | 430 | SKB_GSO_UDP_TUNNEL_CSUM); |
| 397 | if (!tnl_gso_type) | 431 | if (!tnl_gso_type) { |
| 398 | return virtio_net_hdr_from_skb(skb, hdr, little_endian, | 432 | ret = virtio_net_hdr_from_skb(skb, hdr, little_endian, |
| 399 | has_data_valid, vlan_hlen); | 433 | has_data_valid, vlan_hlen); |
| 434 | if (ret) | ||
| 435 | return ret; | ||
| 436 | |||
| 437 | if (feature_hdrlen && hdr->hdr_len) | ||
| 438 | __virtio_net_set_hdrlen(skb, hdr, little_endian); | ||
| 439 | |||
| 440 | return ret; | ||
| 441 | } | ||
| 400 | 442 | ||
| 401 | /* Tunnel support not negotiated but skb ask for it. */ | 443 | /* Tunnel support not negotiated but skb ask for it. */ |
| 402 | if (!tnl_hdr_negotiated) | 444 | if (!tnl_hdr_negotiated) |
| @@ -414,6 +456,9 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb, · 11 unmodified lines | |||
| 414 | if (ret) | 456 | if (ret) |
| 415 | return ret; | 457 | return ret; |
| 416 | 458 | ||
| 459 | if (feature_hdrlen && hdr->hdr_len) | ||
| 460 | __virtio_net_set_tnl_hdrlen(skb, hdr); | ||
| 461 | |||
| 417 | if (skb->protocol == htons(ETH_P_IPV6)) | 462 | if (skb->protocol == htons(ETH_P_IPV6)) |
| 418 | hdr->gso_type |= VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6; | 463 | hdr->gso_type |= VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6; |
| 419 | else | 464 | else |