diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml
index c38cabcb227f..3f244f8788a6 100755
--- a/android/abi_gki_aarch64.xml
+++ b/android/abi_gki_aarch64.xml
@@ -367,6 +367,7 @@
+
@@ -498,6 +499,8 @@
+
+
@@ -634,6 +637,8 @@
+
+
@@ -647,6 +652,7 @@
+
@@ -833,6 +839,7 @@
+
@@ -1852,6 +1859,7 @@
+
@@ -3538,6 +3546,7 @@
+
@@ -6536,6 +6545,7 @@
+
@@ -6667,6 +6677,8 @@
+
+
@@ -6803,6 +6815,8 @@
+
+
@@ -6816,6 +6830,7 @@
+
@@ -7002,6 +7017,7 @@
+
@@ -8876,6 +8892,8 @@
+
+
@@ -10317,21 +10335,21 @@
-
+
-
+
-
+
-
+
-
+
-
+
@@ -15647,6 +15665,89 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -49638,12 +49739,12 @@
-
+
-
+
-
+
@@ -51718,18 +51819,18 @@
-
+
-
+
-
+
-
+
-
+
@@ -52134,12 +52235,12 @@
-
+
-
+
-
+
@@ -54330,12 +54431,12 @@
-
+
-
+
-
+
@@ -55593,6 +55694,7 @@
+
@@ -55894,6 +55996,7 @@
+
@@ -62020,12 +62123,12 @@
-
+
-
+
-
+
@@ -66979,33 +67082,33 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -69111,7 +69214,14 @@
-
+
+
+
+
+
+
+
+
@@ -75250,54 +75360,54 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -84233,54 +84343,54 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -84570,7 +84680,7 @@
-
+
@@ -86935,12 +87045,12 @@
-
+
-
+
-
+
@@ -94507,6 +94617,7 @@
+
@@ -102116,12 +102227,12 @@
-
+
-
+
-
+
@@ -103882,6 +103993,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -108705,66 +108830,66 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -110942,6 +111067,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -114666,99 +114802,99 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
@@ -117154,9 +117290,9 @@
-
+
-
+
@@ -118028,10 +118164,10 @@
-
-
-
-
+
+
+
+
@@ -119332,6 +119468,13 @@
+
+
+
+
+
+
+
@@ -120200,6 +120343,16 @@
+
+
+
+
+
+
+
+
+
+
@@ -120454,11 +120607,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -121061,6 +121214,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -121136,6 +121301,12 @@
+
+
+
+
+
+
@@ -122276,6 +122447,12 @@
+
+
+
+
+
+
@@ -122391,6 +122568,7 @@
+
@@ -122522,6 +122700,8 @@
+
+
@@ -122561,7 +122741,7 @@
-
+
@@ -122658,6 +122838,8 @@
+
+
@@ -122671,6 +122853,7 @@
+
@@ -122857,6 +123040,7 @@
+
@@ -128258,6 +128442,12 @@
+
+
+
+
+
+
@@ -129357,16 +129547,16 @@
-
-
+
+
-
-
+
+
-
-
+
+
@@ -129378,16 +129568,16 @@
-
-
+
+
-
-
+
+
-
-
+
+
@@ -137058,6 +137248,11 @@
+
+
+
+
+
@@ -138324,32 +138519,32 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -140567,8 +140762,8 @@
-
-
+
+
@@ -140599,8 +140794,8 @@
-
-
+
+
@@ -149048,12 +149243,12 @@
-
-
+
+
-
-
+
+
@@ -151686,18 +151881,18 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
diff --git a/android/abi_gki_aarch64_arg b/android/abi_gki_aarch64_arg
index abed76526ed3..c63308bb6f59 100644
--- a/android/abi_gki_aarch64_arg
+++ b/android/abi_gki_aarch64_arg
@@ -293,8 +293,6 @@
debugfs_create_x32
debugfs_create_x64
debugfs_create_x8
- debugfs_file_get
- debugfs_file_put
debugfs_lookup
debugfs_remove
debugfs_rename
@@ -341,6 +339,7 @@
device_for_each_child
device_get_child_node_count
device_get_match_data
+ device_get_named_child_node
device_get_next_child_node
device_initialize
device_init_wakeup
@@ -349,11 +348,13 @@
device_match_name
device_property_present
device_property_read_string
+ device_property_read_string_array
device_property_read_u16_array
device_property_read_u32_array
device_register
device_remove_file
device_rename
+ device_set_wakeup_capable
device_show_int
device_store_int
device_unregister
@@ -398,7 +399,9 @@
devm_kmemdup
devm_krealloc
devm_kstrdup
+ devm_led_classdev_multicolor_register_ext
devm_led_classdev_register_ext
+ devm_mfd_add_devices
devm_nvmem_register
devm_of_clk_add_hw_provider
devm_of_icc_get
@@ -602,12 +605,14 @@
drm_atomic_state_default_release
__drm_atomic_state_free
drm_atomic_state_init
+ drm_bridge_add
drm_bridge_attach
drm_bridge_chain_disable
drm_bridge_chain_enable
drm_bridge_chain_mode_set
drm_bridge_chain_post_disable
drm_bridge_chain_pre_enable
+ drm_bridge_remove
drm_client_init
drm_client_modeset_commit_locked
drm_client_register
@@ -810,6 +815,8 @@
freq_scale
fsync_bdev
fwnode_find_reference
+ fwnode_get_name
+ fwnode_get_named_child_node
fwnode_get_next_child_node
fwnode_handle_get
fwnode_handle_put
@@ -874,6 +881,7 @@
gpiochip_remove
gpiochip_unlock_as_irq
gpiod_cansleep
+ gpiod_count
gpiod_direction_input
gpiod_direction_output
gpiod_direction_output_raw
@@ -882,6 +890,8 @@
gpiod_get_raw_value_cansleep
gpiod_get_value
gpiod_get_value_cansleep
+ gpiod_is_active_low
+ gpiod_set_array_value_cansleep
gpiod_set_consumer_name
gpiod_set_debounce
gpiod_set_raw_value
@@ -924,12 +934,14 @@
__hwspin_unlock
i2c_adapter_type
i2c_add_adapter
+ i2c_add_numbered_adapter
i2c_bus_type
i2c_del_adapter
i2c_del_driver
i2c_for_each_dev
i2c_get_adapter
i2c_get_dma_safe_msg_buf
+ i2c_new_ancillary_device
i2c_new_client_device
i2c_put_adapter
i2c_put_dma_safe_msg_buf
@@ -937,7 +949,9 @@
i2c_smbus_read_byte_data
i2c_smbus_read_i2c_block_data
i2c_smbus_write_byte_data
+ __i2c_smbus_xfer
i2c_smbus_xfer
+ __i2c_transfer
i2c_transfer
i2c_transfer_buffer_flags
i2c_unregister_device
@@ -1203,6 +1217,7 @@
kstrtobool
kstrtoint
kstrtoll
+ kstrtos16
kstrtos8
kstrtou16
kstrtou8
@@ -1243,6 +1258,7 @@
kvmalloc_node
led_classdev_register_ext
led_classdev_unregister
+ led_mc_calc_color_components
led_trigger_event
led_trigger_register_simple
led_trigger_unregister_simple
@@ -1424,6 +1440,7 @@
of_drm_find_bridge
of_find_compatible_node
of_find_device_by_node
+ of_find_i2c_adapter_by_node
of_find_i2c_device_by_node
of_find_matching_node_and_match
of_find_node_by_name
@@ -1438,6 +1455,7 @@
of_get_address
of_get_child_by_name
of_get_cpu_node
+ of_get_i2c_adapter_by_node
of_get_named_gpio_flags
of_get_next_available_child
of_get_next_child
@@ -1487,6 +1505,7 @@
of_property_read_variable_u8_array
of_prop_next_string
of_prop_next_u32
+ of_regulator_match
of_reserved_mem_device_init_by_idx
of_reserved_mem_device_release
of_reserved_mem_lookup
@@ -1733,6 +1752,7 @@
__rcu_read_lock
__rcu_read_unlock
rdev_get_drvdata
+ rdev_get_regmap
reboot_mode
refcount_dec_and_lock
refcount_dec_not_one
@@ -1771,6 +1791,7 @@
__regmap_init
regmap_irq_get_virq
regmap_mmio_detach_clk
+ regmap_multi_reg_write
regmap_read
regmap_update_bits_base
regmap_write
@@ -1874,6 +1895,9 @@
rtc_time64_to_tm
rtc_tm_to_time64
rtc_update_irq
+ rt_mutex_lock
+ rt_mutex_trylock
+ rt_mutex_unlock
rtnl_is_locked
rtnl_lock
rtnl_trylock
@@ -2164,6 +2188,10 @@
thermal_cooling_device_unregister
thermal_of_cooling_device_register
thermal_pressure
+ thermal_zone_device_disable
+ thermal_zone_device_enable
+ thermal_zone_device_register
+ thermal_zone_device_unregister
thermal_zone_device_update
thermal_zone_get_slope
thermal_zone_get_temp
@@ -2173,6 +2201,8 @@
topology_set_thermal_pressure
topology_update_done
total_swapcache_pages
+ touchscreen_parse_properties
+ touchscreen_report_pos
trace_array_put
__trace_bprintk
trace_event_buffer_commit
@@ -2543,3 +2573,7 @@
__xa_insert
xa_load
xa_store
+
+# preserved by --additions-only
+ debugfs_file_get
+ debugfs_file_put
diff --git a/android/abi_gki_aarch64_vivo b/android/abi_gki_aarch64_vivo
index e89b31bc5c7d..b0a167e2971f 100644
--- a/android/abi_gki_aarch64_vivo
+++ b/android/abi_gki_aarch64_vivo
@@ -1687,6 +1687,7 @@
__traceiter_android_rvh_flush_task
__traceiter_android_rvh_migrate_queued_task
__traceiter_android_rvh_new_task_stats
+ __traceiter_android_rvh_percpu_rwsem_wait_complete
__traceiter_android_rvh_refrigerator
__traceiter_android_rvh_replace_next_task_fair
__traceiter_android_rvh_resume_cpus
@@ -1725,6 +1726,8 @@
__traceiter_android_vh_binder_trans
__traceiter_android_vh_binder_wakeup_ilocked
__traceiter_android_vh_blk_alloc_rqs
+ __traceiter_android_vh_clear_rwsem_reader_owned
+ __traceiter_android_vh_clear_rwsem_writer_owned
__traceiter_android_vh_blk_rq_ctx_init
__traceiter_android_vh_cpu_idle_enter
__traceiter_android_vh_cpu_idle_exit
@@ -1750,8 +1753,11 @@
__traceiter_android_vh_mmc_blk_reset
__traceiter_android_vh_mmc_gpio_cd_irqt
__traceiter_android_vh_mm_dirty_limits
+ __traceiter_android_vh_percpu_rwsem_down_read
+ __traceiter_android_vh_percpu_rwsem_up_write
__traceiter_android_vh_printk_hotplug
__traceiter_android_vh_queue_request_and_unlock
+ __traceiter_android_vh_record_rwsem_reader_owned
__traceiter_android_vh_scheduler_tick
__traceiter_android_vh_sdhci_get_cd
__traceiter_android_vh_sd_update_bus_speed_mode
@@ -1791,6 +1797,7 @@
__traceiter_rwmmio_read
__traceiter_rwmmio_write
__traceiter_suspend_resume
+ __traceiter_sys_exit
__traceiter_usb_gadget_connect
__traceiter_usb_gadget_disconnect
__tracepoint_android_rvh_account_irq
@@ -1807,6 +1814,7 @@
__tracepoint_android_rvh_flush_task
__tracepoint_android_rvh_migrate_queued_task
__tracepoint_android_rvh_new_task_stats
+ __tracepoint_android_rvh_percpu_rwsem_wait_complete
__tracepoint_android_rvh_refrigerator
__tracepoint_android_rvh_replace_next_task_fair
__tracepoint_android_rvh_resume_cpus
@@ -1846,6 +1854,8 @@
__tracepoint_android_vh_binder_wakeup_ilocked
__tracepoint_android_vh_blk_alloc_rqs
__tracepoint_android_vh_blk_rq_ctx_init
+ __tracepoint_android_vh_clear_rwsem_reader_owned
+ __tracepoint_android_vh_clear_rwsem_writer_owned
__tracepoint_android_vh_cpu_idle_enter
__tracepoint_android_vh_cpu_idle_exit
__tracepoint_android_vh_do_anonymous_page
@@ -1870,8 +1880,11 @@
__tracepoint_android_vh_mmc_blk_reset
__tracepoint_android_vh_mmc_gpio_cd_irqt
__tracepoint_android_vh_mm_dirty_limits
+ __tracepoint_android_vh_percpu_rwsem_down_read
+ __tracepoint_android_vh_percpu_rwsem_up_write
__tracepoint_android_vh_printk_hotplug
__tracepoint_android_vh_queue_request_and_unlock
+ __tracepoint_android_vh_record_rwsem_reader_owned
__tracepoint_android_vh_scheduler_tick
__tracepoint_android_vh_sdhci_get_cd
__tracepoint_android_vh_sd_update_bus_speed_mode
@@ -1914,6 +1927,7 @@
__tracepoint_rwmmio_read
__tracepoint_rwmmio_write
__tracepoint_suspend_resume
+ __tracepoint_sys_exit
__tracepoint_usb_gadget_connect
__tracepoint_usb_gadget_disconnect
trace_print_array_seq
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index bbb94747bfee..3169bcbc9d13 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -44,6 +44,8 @@
#define CREATE_TRACE_POINTS
#include
+EXPORT_TRACEPOINT_SYMBOL_GPL(sys_exit);
+
struct pt_regs_offset {
const char *name;
int offset;
diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c
index 8e48ff9b8984..92488977dadc 100644
--- a/drivers/android/vendor_hooks.c
+++ b/drivers/android/vendor_hooks.c
@@ -548,6 +548,12 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_wp_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_swap_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_anonymous_page);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_uprobes_replace_page);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_record_rwsem_reader_owned);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_clear_rwsem_reader_owned);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_clear_rwsem_writer_owned);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_percpu_rwsem_down_read);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_percpu_rwsem_up_write);
+EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_percpu_rwsem_wait_complete);
/*
* For type visibility
*/
diff --git a/include/trace/hooks/dtask.h b/include/trace/hooks/dtask.h
index 1e77e78b8c3d..9be71cd609d8 100644
--- a/include/trace/hooks/dtask.h
+++ b/include/trace/hooks/dtask.h
@@ -103,6 +103,15 @@ struct percpu_rw_semaphore;
DECLARE_HOOK(android_vh_percpu_rwsem_wq_add,
TP_PROTO(struct percpu_rw_semaphore *sem, bool reader),
TP_ARGS(sem, reader));
+DECLARE_HOOK(android_vh_percpu_rwsem_down_read,
+ TP_PROTO(struct percpu_rw_semaphore *sem, bool try, bool *ret),
+ TP_ARGS(sem, try, ret));
+DECLARE_HOOK(android_vh_percpu_rwsem_up_write,
+ TP_PROTO(struct percpu_rw_semaphore *sem),
+ TP_ARGS(sem));
+DECLARE_RESTRICTED_HOOK(android_rvh_percpu_rwsem_wait_complete,
+ TP_PROTO(struct percpu_rw_semaphore *sem, long state, bool *complete),
+ TP_ARGS(sem, state, complete), 1);
DECLARE_HOOK(android_vh_exit_check,
TP_PROTO(struct task_struct *tsk, long code, int group_dead),
diff --git a/include/trace/hooks/rwsem.h b/include/trace/hooks/rwsem.h
index ed9daf91f133..72c29b93a8e9 100644
--- a/include/trace/hooks/rwsem.h
+++ b/include/trace/hooks/rwsem.h
@@ -49,6 +49,16 @@ DECLARE_HOOK(android_vh_rwsem_up_read_end,
DECLARE_HOOK(android_vh_rwsem_mark_wake_readers,
TP_PROTO(struct rw_semaphore *sem, struct rwsem_waiter *waiter),
TP_ARGS(sem, waiter));
+DECLARE_HOOK(android_vh_record_rwsem_reader_owned,
+ TP_PROTO(struct rw_semaphore *sem,
+ struct list_head *wlist),
+ TP_ARGS(sem, wlist));
+DECLARE_HOOK(android_vh_clear_rwsem_reader_owned,
+ TP_PROTO(struct rw_semaphore *sem),
+ TP_ARGS(sem));
+DECLARE_HOOK(android_vh_clear_rwsem_writer_owned,
+ TP_PROTO(struct rw_semaphore *sem),
+ TP_ARGS(sem));
/* macro versions of hooks are no longer required */
#endif /* _TRACE_HOOK_RWSEM_H */
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
index b00db54994d8..f3638f973bd3 100644
--- a/kernel/locking/percpu-rwsem.c
+++ b/kernel/locking/percpu-rwsem.c
@@ -181,9 +181,15 @@ static void percpu_rwsem_wait(struct percpu_rw_semaphore *sem, bool reader)
bool __percpu_down_read(struct percpu_rw_semaphore *sem, bool try)
{
+ bool ret = false;
+
if (__percpu_down_read_trylock(sem))
return true;
+ trace_android_vh_percpu_rwsem_down_read(sem, try, &ret);
+ if (ret)
+ return true;
+
if (try)
return false;
@@ -230,6 +236,8 @@ static bool readers_active_check(struct percpu_rw_semaphore *sem)
void percpu_down_write(struct percpu_rw_semaphore *sem)
{
+ bool complete = false;
+
might_sleep();
rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
@@ -252,7 +260,9 @@ void percpu_down_write(struct percpu_rw_semaphore *sem)
*/
/* Wait for all active readers to complete. */
- rcuwait_wait_event(&sem->writer, readers_active_check(sem), TASK_UNINTERRUPTIBLE);
+ trace_android_rvh_percpu_rwsem_wait_complete(sem, TASK_UNINTERRUPTIBLE, &complete);
+ if (!complete)
+ rcuwait_wait_event(&sem->writer, readers_active_check(sem), TASK_UNINTERRUPTIBLE);
trace_android_vh_record_pcpu_rwsem_starttime(current, jiffies);
}
EXPORT_SYMBOL_GPL(percpu_down_write);
@@ -261,6 +271,8 @@ void percpu_up_write(struct percpu_rw_semaphore *sem)
{
rwsem_release(&sem->dep_map, _RET_IP_);
+ trace_android_vh_percpu_rwsem_up_write(sem);
+
/*
* Signal the writer is done, no fast path yet.
*
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
index 3527850a60a1..830cd4bd4c7b 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -182,6 +182,7 @@ static inline void rwsem_set_owner(struct rw_semaphore *sem)
static inline void rwsem_clear_owner(struct rw_semaphore *sem)
{
atomic_long_set(&sem->owner, 0);
+ trace_android_vh_clear_rwsem_writer_owned(sem);
}
/*
@@ -245,6 +246,7 @@ static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
{
unsigned long val = atomic_long_read(&sem->owner);
+ trace_android_vh_clear_rwsem_reader_owned(sem);
while ((val & ~RWSEM_OWNER_FLAGS_MASK) == (unsigned long)current) {
if (atomic_long_try_cmpxchg(&sem->owner, &val,
val & RWSEM_OWNER_FLAGS_MASK))
@@ -254,6 +256,7 @@ static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
#else
static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
{
+ trace_android_vh_clear_rwsem_reader_owned(sem);
}
#endif
@@ -528,6 +531,7 @@ static void rwsem_mark_wake(struct rw_semaphore *sem,
if (adjustment)
atomic_long_add(adjustment, &sem->count);
+ trace_android_vh_record_rwsem_reader_owned(sem, &wlist);
/* 2nd pass */
list_for_each_entry_safe(waiter, tmp, &wlist, list) {
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 08aaa6efc62c..e0e16b0fdb17 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -437,12 +437,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct netem_sched_data *q = qdisc_priv(sch);
/* We don't fill cb now as skb_unshare() may invalidate it */
struct netem_skb_cb *cb;
- struct sk_buff *skb2;
+ struct sk_buff *skb2 = NULL;
struct sk_buff *segs = NULL;
unsigned int prev_len = qdisc_pkt_len(skb);
int count = 1;
- int rc = NET_XMIT_SUCCESS;
- int rc_drop = NET_XMIT_DROP;
/* Do not fool qdisc_drop_all() */
skb->prev = NULL;
@@ -471,19 +469,11 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
skb_orphan_partial(skb);
/*
- * If we need to duplicate packet, then re-insert at top of the
- * qdisc tree, since parent queuer expects that only one
- * skb will be queued.
+ * If we need to duplicate packet, then clone it before
+ * original is modified.
*/
- if (count > 1 && (skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
- struct Qdisc *rootq = qdisc_root_bh(sch);
- u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
-
- q->duplicate = 0;
- rootq->enqueue(skb2, rootq, to_free);
- q->duplicate = dupsave;
- rc_drop = NET_XMIT_SUCCESS;
- }
+ if (count > 1)
+ skb2 = skb_clone(skb, GFP_ATOMIC);
/*
* Randomized packet corruption.
@@ -495,7 +485,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (skb_is_gso(skb)) {
skb = netem_segment(skb, sch, to_free);
if (!skb)
- return rc_drop;
+ goto finish_segs;
+
segs = skb->next;
skb_mark_not_on_list(skb);
qdisc_skb_cb(skb)->pkt_len = skb->len;
@@ -521,7 +512,24 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
/* re-link segs, so that qdisc_drop_all() frees them all */
skb->next = segs;
qdisc_drop_all(skb, sch, to_free);
- return rc_drop;
+ if (skb2)
+ __qdisc_drop(skb2, to_free);
+ return NET_XMIT_DROP;
+ }
+
+ /*
+ * If doing duplication then re-insert at top of the
+ * qdisc tree, since parent queuer expects that only one
+ * skb will be queued.
+ */
+ if (skb2) {
+ struct Qdisc *rootq = qdisc_root_bh(sch);
+ u32 dupsave = q->duplicate; /* prevent duplicating a dup... */
+
+ q->duplicate = 0;
+ rootq->enqueue(skb2, rootq, to_free);
+ q->duplicate = dupsave;
+ skb2 = NULL;
}
qdisc_qstats_backlog_inc(sch, skb);
@@ -592,9 +600,12 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
}
finish_segs:
+ if (skb2)
+ __qdisc_drop(skb2, to_free);
+
if (segs) {
unsigned int len, last_len;
- int nb;
+ int rc, nb;
len = skb ? skb->len : 0;
nb = skb ? 1 : 0;