[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240801105707.30021-1-wojciech.gladysz@infogain.com>
Date: Thu, 1 Aug 2024 12:57:07 +0200
From: Wojciech Gładysz <wojciech.gladysz@...ogain.com>
To: davem@...emloft.net,
edumazet@...gle.com,
kuba@...nel.org,
pabeni@...hat.com,
jhs@...atatu.com,
xiyou.wangcong@...il.com,
jiri@...nulli.us,
netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: Wojciech Gładysz <wojciech.gladysz@...ogain.com>
Subject: [PATCH] kernel/net: missused TCQ_F_NOLOCK flag
TCQ_F_NOLOCK yields no locking option for a qdisc. At some places in the
code the testing for the flag seems logically reverted. The change fixes
the following lockdep issue.
======================================================
WARNING: possible circular locking dependency detected
5.10.0-syzkaller #0 Not tainted
------------------------------------------------------
syz-executor372/2662 is trying to acquire lock:
ffff888028151218 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2){+...}-{2:2}, at: spin_lock include/linux/spinlock.h:357 [inline]
ffff888028151218 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2){+...}-{2:2}, at: __dev_xmit_skb net/core/dev.c:3689 [inline]
ffff888028151218 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2){+...}-{2:2}, at: __dev_queue_xmit+0x1e02/0x32b0 net/core/dev.c:4053
but task is already holding lock:
ffff88801016d0d8 (&qdisc_xmit_lock_key){+...}-{2:2}, at: spin_lock include/linux/spinlock.h:357 [inline]
ffff88801016d0d8 (&qdisc_xmit_lock_key){+...}-{2:2}, at: __netif_tx_lock include/linux/netdevice.h:4077 [inline]
ffff88801016d0d8 (&qdisc_xmit_lock_key){+...}-{2:2}, at: sch_direct_xmit+0x19c/0x9c0 net/sched/sch_generic.c:341
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&qdisc_xmit_lock_key){+...}-{2:2}:
lock_acquire+0x197/0x480 kernel/locking/lockdep.c:5566
__raw_spin_lock include/linux/spinlock_api_smp.h:144 [inline]
_raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:151
spin_lock include/linux/spinlock.h:357 [inline]
__netif_tx_lock include/linux/netdevice.h:4077 [inline]
sch_direct_xmit+0x19c/0x9c0 net/sched/sch_generic.c:341
__dev_xmit_skb net/core/dev.c:3663 [inline]
__dev_queue_xmit+0x158e/0x32b0 net/core/dev.c:4053
dev_queue_xmit+0x17/0x20 net/core/dev.c:4121
neigh_resolve_output+0x644/0x750 net/core/neighbour.c:1508
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
NF_HOOK+0x166/0x550 include/linux/netfilter.h:309
mld_sendpack+0x823/0xd90 net/ipv6/mcast.c:1817
mld_send_cr net/ipv6/mcast.c:2118 [inline]
mld_ifc_work+0x814/0xcc0 net/ipv6/mcast.c:2649
process_one_work+0x857/0xfd0 kernel/workqueue.c:2282
worker_thread+0xafa/0x1550 kernel/workqueue.c:2428
kthread+0x374/0x3f0 kernel/kthread.c:349
ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:306
-> #0 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2){+...}-{2:2}:
check_prev_add kernel/locking/lockdep.c:2988 [inline]
check_prevs_add kernel/locking/lockdep.c:3113 [inline]
validate_chain+0x1695/0x58f0 kernel/locking/lockdep.c:3729
__lock_acquire+0x12fd/0x20d0 kernel/locking/lockdep.c:4955
lock_acquire+0x197/0x480 kernel/locking/lockdep.c:5566
__raw_spin_lock include/linux/spinlock_api_smp.h:144 [inline]
_raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:151
spin_lock include/linux/spinlock.h:357 [inline]
__dev_xmit_skb net/core/dev.c:3689 [inline]
__dev_queue_xmit+0x1e02/0x32b0 net/core/dev.c:4053
dev_queue_xmit+0x17/0x20 net/core/dev.c:4121
neigh_resolve_output+0x644/0x750 net/core/neighbour.c:1508
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
NF_HOOK include/linux/netfilter.h:309 [inline]
ndisc_send_skb+0xaaa/0x1370 net/ipv6/ndisc.c:508
ndisc_solicit+0x3ea/0x660 net/ipv6/ndisc.c:666
neigh_probe net/core/neighbour.c:1021 [inline]
__neigh_event_send+0xec0/0x1460 net/core/neighbour.c:1182
neigh_event_send include/net/neighbour.h:457 [inline]
neigh_resolve_output+0x1cf/0x750 net/core/neighbour.c:1492
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161
ip6_send_skb+0x127/0x220 net/ipv6/ip6_output.c:2015
ip6_push_pending_frames+0xb4/0xe0 net/ipv6/ip6_output.c:2035
icmpv6_push_pending_frames+0x2f4/0x4b0 net/ipv6/icmp.c:304
icmp6_send+0x160c/0x20d0 net/ipv6/icmp.c:627
__icmpv6_send include/linux/icmpv6.h:28 [inline]
icmpv6_send include/linux/icmpv6.h:49 [inline]
ip6_link_failure+0x3b/0x4c0 net/ipv6/route.c:2801
dst_link_failure include/net/dst.h:423 [inline]
ip_tunnel_xmit+0x1b76/0x2b40 net/ipv4/ip_tunnel.c:856
__gre_xmit net/ipv4/ip_gre.c:471 [inline]
erspan_xmit+0xb22/0x1380 net/ipv4/ip_gre.c:728
__netdev_start_xmit include/linux/netdevice.h:4657 [inline]
netdev_start_xmit include/linux/netdevice.h:4671 [inline]
xmit_one net/core/dev.c:3455 [inline]
dev_hard_start_xmit+0x36a/0x880 net/core/dev.c:3471
sch_direct_xmit+0x2a0/0x9c0 net/sched/sch_generic.c:343
qdisc_restart net/sched/sch_generic.c:408 [inline]
__qdisc_run+0xae6/0x1cb0 net/sched/sch_generic.c:416
__dev_xmit_skb net/core/dev.c:3722 [inline]
__dev_queue_xmit+0xdd5/0x32b0 net/core/dev.c:4053
dev_queue_xmit+0x17/0x20 net/core/dev.c:4121
neigh_resolve_output+0x644/0x750 net/core/neighbour.c:1508
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
NF_HOOK include/linux/netfilter.h:309 [inline]
rawv6_send_hdrinc+0xd16/0x1930 net/ipv6/raw.c:669
rawv6_sendmsg+0x15e5/0x2100 net/ipv6/raw.c:929
inet_sendmsg+0x149/0x310 net/ipv4/af_inet.c:854
sock_sendmsg_nosec net/socket.c:702 [inline]
__sock_sendmsg net/socket.c:714 [inline]
sock_write_iter+0x3a0/0x520 net/socket.c:1088
call_write_iter include/linux/fs.h:1986 [inline]
new_sync_write fs/read_write.c:518 [inline]
vfs_write+0x9c0/0xc30 fs/read_write.c:605
ksys_write+0x17e/0x2a0 fs/read_write.c:658
__do_sys_write fs/read_write.c:670 [inline]
__se_sys_write fs/read_write.c:667 [inline]
__x64_sys_write+0x7b/0x90 fs/read_write.c:667
do_syscall_64+0x6d/0xa0 arch/x86/entry/common.c:62
entry_SYSCALL_64_after_hwframe+0x61/0xcb
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&qdisc_xmit_lock_key);
lock(dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2);
lock(&qdisc_xmit_lock_key);
lock(dev->qdisc_tx_busylock ?: &qdisc_tx_busylock#2);
*** DEADLOCK ***
11 locks held by syz-executor372/2662:
#0: ffffffff8806ed80 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x9/0x40 include/linux/rcupdate.h:272
#1: ffffffff8806ed80 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x9/0x40 include/linux/rcupdate.h:272
#2: ffffffff8806ede0 (rcu_read_lock_bh){....}-{1:2}, at: rcu_lock_acquire+0xd/0x40 include/linux/rcupdate.h:273
#3: ffff888028151148 (dev->qdisc_running_key ?: &qdisc_running_key){+...}-{0:0}, at: dev_queue_xmit+0x17/0x20 net/core/dev.c:4121
#4: ffff88801016d0d8 (&qdisc_xmit_lock_key){+...}-{2:2}, at: spin_lock include/linux/spinlock.h:357 [inline]
#4: ffff88801016d0d8 (&qdisc_xmit_lock_key){+...}-{2:2}, at: __netif_tx_lock include/linux/netdevice.h:4077 [inline]
#4: ffff88801016d0d8 (&qdisc_xmit_lock_key){+...}-{2:2}, at: sch_direct_xmit+0x19c/0x9c0 net/sched/sch_generic.c:341
#5: ffff88801691a218 (k-slock-AF_INET6){+...}-{2:2}, at: spin_trylock include/linux/spinlock.h:367 [inline]
#5: ffff88801691a218 (k-slock-AF_INET6){+...}-{2:2}, at: icmpv6_xmit_lock net/ipv6/icmp.c:109 [inline]
#5: ffff88801691a218 (k-slock-AF_INET6){+...}-{2:2}, at: icmp6_send+0xa79/0x20d0 net/ipv6/icmp.c:545
#6: ffffffff8806ed80 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x9/0x40 include/linux/rcupdate.h:272
#7: ffffffff8806ed80 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x9/0x40 include/linux/rcupdate.h:272
#8: ffffffff8806ed80 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x9/0x40 include/linux/rcupdate.h:272
#9: ffffffff8806ed80 (rcu_read_lock){....}-{1:2}, at: rcu_lock_acquire+0x9/0x40 include/linux/rcupdate.h:272
#10: ffffffff8806ede0 (rcu_read_lock_bh){....}-{1:2}, at: rcu_lock_acquire+0xd/0x40 include/linux/rcupdate.h:273
stack backtrace:
CPU: 1 PID: 2662 Comm: syz-executor372 Not tainted 5.10.0-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x177/0x211 lib/dump_stack.c:118
print_circular_bug+0x146/0x1b0 kernel/locking/lockdep.c:2002
check_noncircular+0x2cc/0x390 kernel/locking/lockdep.c:2123
check_prev_add kernel/locking/lockdep.c:2988 [inline]
check_prevs_add kernel/locking/lockdep.c:3113 [inline]
validate_chain+0x1695/0x58f0 kernel/locking/lockdep.c:3729
__lock_acquire+0x12fd/0x20d0 kernel/locking/lockdep.c:4955
lock_acquire+0x197/0x480 kernel/locking/lockdep.c:5566
__raw_spin_lock include/linux/spinlock_api_smp.h:144 [inline]
_raw_spin_lock+0x2a/0x40 kernel/locking/spinlock.c:151
spin_lock include/linux/spinlock.h:357 [inline]
__dev_xmit_skb net/core/dev.c:3689 [inline]
__dev_queue_xmit+0x1e02/0x32b0 net/core/dev.c:4053
dev_queue_xmit+0x17/0x20 net/core/dev.c:4121
neigh_resolve_output+0x644/0x750 net/core/neighbour.c:1508
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
NF_HOOK include/linux/netfilter.h:309 [inline]
ndisc_send_skb+0xaaa/0x1370 net/ipv6/ndisc.c:508
ndisc_solicit+0x3ea/0x660 net/ipv6/ndisc.c:666
neigh_probe net/core/neighbour.c:1021 [inline]
__neigh_event_send+0xec0/0x1460 net/core/neighbour.c:1182
neigh_event_send include/net/neighbour.h:457 [inline]
neigh_resolve_output+0x1cf/0x750 net/core/neighbour.c:1492
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
ip6_local_out+0x10f/0x140 net/ipv6/output_core.c:161
ip6_send_skb+0x127/0x220 net/ipv6/ip6_output.c:2015
ip6_push_pending_frames+0xb4/0xe0 net/ipv6/ip6_output.c:2035
icmpv6_push_pending_frames+0x2f4/0x4b0 net/ipv6/icmp.c:304
icmp6_send+0x160c/0x20d0 net/ipv6/icmp.c:627
__icmpv6_send include/linux/icmpv6.h:28 [inline]
icmpv6_send include/linux/icmpv6.h:49 [inline]
ip6_link_failure+0x3b/0x4c0 net/ipv6/route.c:2801
dst_link_failure include/net/dst.h:423 [inline]
ip_tunnel_xmit+0x1b76/0x2b40 net/ipv4/ip_tunnel.c:856
__gre_xmit net/ipv4/ip_gre.c:471 [inline]
erspan_xmit+0xb22/0x1380 net/ipv4/ip_gre.c:728
__netdev_start_xmit include/linux/netdevice.h:4657 [inline]
netdev_start_xmit include/linux/netdevice.h:4671 [inline]
xmit_one net/core/dev.c:3455 [inline]
dev_hard_start_xmit+0x36a/0x880 net/core/dev.c:3471
sch_direct_xmit+0x2a0/0x9c0 net/sched/sch_generic.c:343
qdisc_restart net/sched/sch_generic.c:408 [inline]
__qdisc_run+0xae6/0x1cb0 net/sched/sch_generic.c:416
__dev_xmit_skb net/core/dev.c:3722 [inline]
__dev_queue_xmit+0xdd5/0x32b0 net/core/dev.c:4053
dev_queue_xmit+0x17/0x20 net/core/dev.c:4121
neigh_resolve_output+0x644/0x750 net/core/neighbour.c:1508
neigh_output include/net/neighbour.h:528 [inline]
ip6_finish_output2+0x150b/0x1ea0 net/ipv6/ip6_output.c:151
__ip6_finish_output+0x4b6/0x620 net/ipv6/ip6_output.c:224
ip6_finish_output+0x34/0x280 net/ipv6/ip6_output.c:234
NF_HOOK_COND include/linux/netfilter.h:298 [inline]
ip6_output+0x2c4/0x3d0 net/ipv6/ip6_output.c:257
dst_output include/net/dst.h:444 [inline]
NF_HOOK include/linux/netfilter.h:309 [inline]
rawv6_send_hdrinc+0xd16/0x1930 net/ipv6/raw.c:669
rawv6_sendmsg+0x15e5/0x2100 net/ipv6/raw.c:929
inet_sendmsg+0x149/0x310 net/ipv4/af_inet.c:854
sock_sendmsg_nosec net/socket.c:702 [inline]
__sock_sendmsg net/socket.c:714 [inline]
sock_write_iter+0x3a0/0x520 net/socket.c:1088
call_write_iter include/linux/fs.h:1986 [inline]
new_sync_write fs/read_write.c:518 [inline]
vfs_write+0x9c0/0xc30 fs/read_write.c:605
ksys_write+0x17e/0x2a0 fs/read_write.c:658
__do_sys_write fs/read_write.c:670 [inline]
__se_sys_write fs/read_write.c:667 [inline]
__x64_sys_write+0x7b/0x90 fs/read_write.c:667
do_syscall_64+0x6d/0xa0 arch/x86/entry/common.c:62
entry_SYSCALL_64_after_hwframe+0x61/0xcb
RIP: 0033:0x7fd7b2201c69
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 d1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffe960e0cb8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fd7b2201c69
RDX: 0000000000000028 RSI: 0000000020000140 RDI: 0000000000000006
RBP: 00000000000f4240 R08: 0000000100000000 R09: 0000000100000000
R10: 0000000100000000 R11: 0000000000000246 R12: 00007ffe960e0d10
R13: 0000000000000001 R14: 00007ffe960e0d10 R15: 0000000000000003
Signed-off-by: Wojciech Gładysz <wojciech.gladysz@...ogain.com>
---
include/net/sch_generic.h | 6 +++---
net/sched/sch_generic.c | 12 ++++++------
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 79edd5b5e3c9..35a747e3c00a 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -166,7 +166,7 @@ static inline struct Qdisc *qdisc_refcount_inc_nz(struct Qdisc *qdisc)
*/
static inline bool qdisc_is_running(struct Qdisc *qdisc)
{
- if (qdisc->flags & TCQ_F_NOLOCK)
+ if (!(qdisc->flags & TCQ_F_NOLOCK))
return spin_is_locked(&qdisc->seqlock);
return test_bit(__QDISC_STATE2_RUNNING, &qdisc->state2);
}
@@ -193,7 +193,7 @@ static inline bool qdisc_is_empty(const struct Qdisc *qdisc)
*/
static inline bool qdisc_run_begin(struct Qdisc *qdisc)
{
- if (qdisc->flags & TCQ_F_NOLOCK) {
+ if (!(qdisc->flags & TCQ_F_NOLOCK)) {
if (spin_trylock(&qdisc->seqlock))
return true;
@@ -216,7 +216,7 @@ static inline bool qdisc_run_begin(struct Qdisc *qdisc)
static inline void qdisc_run_end(struct Qdisc *qdisc)
{
- if (qdisc->flags & TCQ_F_NOLOCK) {
+ if (!(qdisc->flags & TCQ_F_NOLOCK)) {
spin_unlock(&qdisc->seqlock);
/* spin_unlock() only has store-release semantic. The unlock
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index e22ff003d52e..db24f477e310 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -76,7 +76,7 @@ static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
spinlock_t *lock = NULL;
struct sk_buff *skb;
- if (q->flags & TCQ_F_NOLOCK) {
+ if (!(q->flags & TCQ_F_NOLOCK)) {
lock = qdisc_lock(q);
spin_lock(lock);
}
@@ -121,7 +121,7 @@ static inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q,
{
spinlock_t *lock = NULL;
- if (q->flags & TCQ_F_NOLOCK) {
+ if (!(q->flags & TCQ_F_NOLOCK)) {
lock = qdisc_lock(q);
spin_lock(lock);
}
@@ -144,7 +144,7 @@ static inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
{
spinlock_t *lock = NULL;
- if (q->flags & TCQ_F_NOLOCK) {
+ if (!(q->flags & TCQ_F_NOLOCK)) {
lock = qdisc_lock(q);
spin_lock(lock);
}
@@ -236,7 +236,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
if (unlikely(!skb_queue_empty(&q->gso_skb))) {
spinlock_t *lock = NULL;
- if (q->flags & TCQ_F_NOLOCK) {
+ if (!(q->flags & TCQ_F_NOLOCK)) {
lock = qdisc_lock(q);
spin_lock(lock);
}
@@ -1300,14 +1300,14 @@ static void dev_reset_queue(struct net_device *dev,
nolock = qdisc->flags & TCQ_F_NOLOCK;
- if (nolock)
+ if (!nolock)
spin_lock_bh(&qdisc->seqlock);
spin_lock_bh(qdisc_lock(qdisc));
qdisc_reset(qdisc);
spin_unlock_bh(qdisc_lock(qdisc));
- if (nolock) {
+ if (!nolock) {
clear_bit(__QDISC_STATE_MISSED, &qdisc->state);
clear_bit(__QDISC_STATE_DRAINING, &qdisc->state);
spin_unlock_bh(&qdisc->seqlock);
--
2.35.3
Powered by blists - more mailing lists