From: BlaisorBlade <bla...@ya...> - 2004-09-25 17:37:38
|
On Monday 20 September 2004 21:55, Stroesser, Bodo wrote: > Today I tried testing interrupted systemcalls on UML 2.6.8.1-1 with the > incremental patches up to skas-flush-tlb. My host does not yet support > the new SYSEMU-ptrace. > > In skas-mode, the uml system with this kernel doesn't boot! It panics > with the message: > Kernel panic: handle_trap - failed to wait at end of syscall, errno = 4, > status = 4479 > Tracking this down I saw that "errno = 4" from the message is > misleading! > It's an old errno, the return value of waitpid() is the pid > of the user-thread. It seems to be stopped by SIGCHLD. Yes, I get some similar failures with the misleading "errno = 4"; I guess it's time to fix, maybe, either CATCH_EINTR or just this invocation of it. However, the problem that UML should not expect the child getting only those virtual SIGTRAP (see man 2 ptrace); any other signal in that point should IMHO just be ignored. I've not written the patch but it is just adding Yet Another Loop, beyond the CATCH_EINTR one (this time no general macro are needed). > I do not understand exactly what happens, but the signal seems to be > generated while running handle_syscall() called from handle_trap(). > Changing back to the sequence of calling waitpid() and handle_syscall() > as it has been before the sysemu-patch removed the problem. > Here is my patch (I also changed the panic message to include "err" and > to print status in Hex): This particular part is Ok, but could you, please, avoid trumpling over and removing the sysemu code? It's absolutely not needed. If you enclose the last two ptrace calls in "if (!use_sysemu)" and you move the "handle_syscall" after them, you get your fix + no change for sysemu. > --- tmp/linux-2.6.8.1/arch/um/kernel/skas/process.c 2004-09-17 > 19:20:15.000000000 +0200 > > +++ linux-2.6.8.1/arch/um/kernel/skas/process.c 2004-09-20 > 21:31:39.451946258 +0200 > > @@ -68,25 +68,25 @@ > > return; > > } > > > > - handle_syscall(regs); > A side note: posting HTML messages is bad (on LKML it is enough to be totally & completely ignored, I guess); and the above is what the inline patch becomes while answering to an HTML message - could you please either send plain-text or move the patches to attachments (I strongly prefer the first solution)? Bye -- Paolo Giarrusso, aka Blaisorblade Linux registered user n. 292729 |
From: COEX <ic...@in...> - 2005-02-12 00:01:11
|
From: andrea <ker...@gm...> - 2005-03-17 17:08:00
|
From: William S. <wst...@po...> - 2005-03-20 22:05:17
|
Good day, all, Charlyn Dike! Jeff and Charlyn were married yesterday in Boston Mass, USA in a small ceremony near the MIT campus. The two of them will be traveling for a few weeks. Jeff is unlikely to be near a good Internet connection for a while, so we should find our own UML answers until he gets back. Jeff and Charlyn, I'd like to wish you the best of luck and happiness in your life together. Cheers, - Bill --------------------------------------------------------------------------- "There is no beautifier of complexion or form of behavior like the wish to scatter joy, and not pain, around us." -- Ralph Waldo Emerson -------------------------------------------------------------------------- William Stearns (wst...@po...). Mason, Buildkernel, freedups, p0f, rsync-backup, ssh-keyinstall, dns-check, more at: http://www.stearns.org -------------------------------------------------------------------------- |
From: <zh...@16...> - 2006-04-10 14:40:04
|
From: xmyl <xmy...@16...> - 2006-12-22 23:34:42
|
知名劳动法专家梁硕南、郑建中联合主讲精典课程 ●最新劳动争议司法解释解读、劳动争议处理技巧及典型案例分析 ●如何规范员工的入职、在职和离职管理及如何对问题员工降职、降薪、调岗、辞退 主办单位:深圳梁硕南劳动咨询事务所 深圳市企业联合会 深圳市企业家协会 中国劳动人事网www.cn12333.com、深圳企业劳动维权网www.sz12333.com 时 间:2007年1月12日(星期五)9:00-17:30 地 点:深圳市深南东路2023号广深大厦(广深宾馆)四楼多功能厅 费 用:(1)只报一个课程(半天)的,同一单位1人参加的450元、2人参加的每人350元、3人或3人以上参加的每人250元; (2)同时报两个课程(一天)的,同一单位1人参加的650元、2人参加的每人500元、3人或3人以上参加的每人400元。 优 惠:2006年12月7前已报名并缴费的,按上述收费标准7折优惠;12月25报名并缴费的,8折优惠;2007年1月10日前报名并 缴费的,9折优惠;中国劳动人事网和深圳企业劳动维权网会员按会员合同约定的标准收费;参加过中国劳动人事网和深圳企业 劳动维权网培训的企业8折优惠;。 主讲老师一:梁硕南先生,知名劳动人事法律专家,资深培训讲师,中山大学行政管理和法律专业双学历,中国劳动人事网和深 圳企业劳动维权网总经理兼首席法律顾问,《中国劳动人事政策法规专刊》主编,原广东国扬律师事务所劳动争议法律服务部部 长,现深圳梁硕南劳动咨询事务所创办人兼主任,中国劳动法学研究会会员。 主讲老师二:郑建中先生,知名劳动法专家,资深培训讲师,《中国劳动人事政策法规专刊》副主编,深圳梁硕南劳动咨询事务 所副主任。从事法官工作12年,历任审判员、庭长等职。 课程大纲(详细大纲及其他事宜请登陆www.cn12333.com, www.sz12333.com 了解) ●最新司法解释解读、劳动争议处理技巧及典型案例分析(1月12日上午郑建中主讲) 一 、最高人民法院关于审理劳动争议案件适用法律问题的最新司法解释解读; 二、广东省高院和深圳市中院关于审理劳动争议案件适用法律问题的最新指导意见解读; 三、 劳动争议常见问题与处理技巧 …… ●如何规范员工的入职、在职和离职管理及如何对问题员工降职、降薪、调岗、辞退(1月12日下午梁硕南主讲) 一、如何规范员工的入职管理、在职管理和离职管理 (一)入职登记表的设计要求及必备内容(此表设计的好坏关乎劳动争议的多少和胜败)。 (二)员工入职之后,在员工自愿的前提下,对财务、采购等特殊人员可否收取风险金? (三)合同期与服务期的区别与应用,如何约定培训后的合同期或服务期和违约赔偿条款? …… 二、如何依法对问题员工降职、降薪、调岗、辞退及其争议处理 (一)对问题员工降职、降薪、调岗、辞退的法律依据和处理原则; (二)对问题员工降职、降薪、调岗、辞退的实际操作程序和技巧; (三)降职、降薪、调岗、辞退问题员工争议中企业败诉原因分析 (四)如何避免和应对由于降职、降薪、调岗、辞退引起的劳动争议? …… 报名电话:0755-28281809 28282755 联系人:郑先生、张小姐、李小姐、范小姐 |
From: <wor...@16...> - 2006-12-26 01:04:54
|
From:
<eye...@ho...> - 2007-02-05 10:22:51
|
※※※※※※※※※※※┏※※※※※※※※※※※※※※※※※※※※┓ ※※※※※※※※※※※┃※※※※※※※※※※┌──────┐※※┃ ※★━━━┓※※※※※┃※※※●●●●●※※│★完全無料★│※※┃ ※┃出会い┣━━┓※※┃※※●●※※※●●※└──────┘※※┃ ※┗━━━┛※※┃※※┃※※●●※※※●●※※※※※※※※※※※┃ ※★━━━┓※※┃※※┃※※●●※※※●●※※※※※※※※※※※┃ ※┃登録費┣━━╋━━┫※※●●※※※●●※※■■■■■※※※※┃ ※┗━━━┛※※┃※※┃※※●●※※※●●※※■※■※■※※※※┃ ※★━━━┓※※┃※※┃※※●●※※※●●※※■■■■■※※※※┃ ※┃年会費┣━━┛※※┃※※●●※※※●●※※■※※※■※※※※┃ ※┗━━━┛※※※※※┃※※※●●●●●※※※■※※■■※※※※┃ ※※※※※※※※※※※┗※※※※※※※※※※※※※※※※※※※※┛ http://isshonine.com/LM/ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃【1】他のサイトとここが違う!!☆ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【安心・安全】男性だけでなく、女性に優しいサービスが満点!↓ ……………………………………………………… ・セキュリティ万全! ・安心サポート! ・個人情報徹底保護! ・メールアドレス非公開! 不安を無くして理想の人と結ばれるチャンスです! 安心して恋人を探すことができます。 http://isshonine.com/LM/ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃【2】☆超便利!あなたのニーズにサイトが対応しちゃいます!! ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ↓簡単アクセス★↓ ……………………………………… パソコンが苦手な女性でも大丈夫! 出先から家から、場所を選ばすに使えます♪ いつでも自由に恋人探し! http://isshonine.com/LM/ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ┃【3】☆本日のプロフィール大公開!! ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 真央 23歳 経験が浅いから色んなエッチを知りません。 した事があるのは正常位と騎乗位とフェラと69くらいです。 他に何か知ってる人がいたら伝授してくれませんか? 必ず守ってもらいたい事は生理の時以外は必ず避妊して下さい。 あと病気を持ってる人はもっての他です。 松山に住んでる長身(173/53)の真央です。 ……………………………………………………………………………… かずみ 26歳 気軽に会える人がいいんですけど、彼氏募集ってわけじゃなくて、 快楽追求目的で、会いたくなった時にフラッと会いたいです。 束縛とか無しで、少し距離を保った感じが理想なので、 相手がいる人でもOKです!新宿で歯科助手してます。26です(_ _) ……………………………………………………………………………… 未来 20歳 横浜生息の「未来」20歳です。 不思議なくらいおっぱいだけが異常に感じます。 あたしのぷるんぷるんFカップっておかしいのかな? いちおう彼氏いるけど、忙しくて月1くらいしか出来ないんで、 あたしのすけべなおっぱいにいやらしい言葉をたくさんかけて いぢめてくれるおっぱい大好きさんに会いたいです。 ……………………………………………………………………………… 奈津美 28歳 平日の仕事帰りあたりに遊びませんか? お食事やカラオケや、エッチできるやり友達がほしいんです!28の川崎市です。 メイル待ってます! |
From: <dho...@re...> - 2007-10-01 16:06:43
|
>From dhowells Mon Oct 1 14: 11:57 2007 Return-Path: <dho...@re...> Received: from localhost.localdomain [127.0.0.1] by warthog.procyon.org.uk with IMAP (fetchmail-6.3.7) for <dhowells@localhost> (single-drop); Mon, 01 Oct 2007 14:11:57 +0100 (BST) Received: from pobox.devel.redhat.com ([unix socket]) by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA; Mon, 01 Oct 2007 09:11:45 -0400 X-Sieve: CMU Sieve 2.2 Received: from warthog.cambridge.redhat.com (devserv.devel.redhat.com [10.10.36.72]) by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l91DBimG031190; Mon, 1 Oct 2007 09:11:45 -0400 Received: from [127.0.0.1] (helo=warthog.procyon.org.uk) by warthog.cambridge.redhat.com with esmtp (Exim 4.66 #1 (Red Hat Linux)) id 1IcL3p-0007hp-1L; Mon, 01 Oct 2007 14:11:45 +0100 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells <dho...@re...> Subject: [PATCH 28/30] IGET: Stop HOSTFS from using iget() and read_inode() To: hc...@in..., vi...@ft..., tor...@os..., ak...@os... Cc: lin...@vg..., lin...@vg..., dho...@re... Date: Mon, 01 Oct 2007 14:11:45 +0100 Message-ID: <200...@wa...> In-Reply-To: <200...@wa...> References: <200...@wa...> User-Agent: StGIT/0.13 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Resent-To: use...@li... Resent-cc: jd...@ka... Resent-Date: Mon, 01 Oct 2007 17:06:27 +0100 Resent-Message-ID: <191...@re...> Resent-From: David Howells <dho...@re...> Stop the HOSTFS filesystem from using iget() and read_inode(). Provide hostfs_iget(), and call that instead of iget(). hostfs_iget() then uses iget_locked() directly and returns a proper error code instead of an inode in the event of an error. hostfs_fill_sb_common() returns any error incurred when getting the root inode instead of EINVAL. Note that the contents of hostfs_kern.c need to be examined: (*) hostfs_iget() should perhaps subsume init_inode() and hostfs_read_inode(). (*) It would appear that all hostfs inodes are the same inode because iget() was being called with inode number 0 - which forms the lookup key. Signed-off-by: David Howells <dho...@re...> --- fs/hostfs/hostfs_kern.c | 58 ++++++++++++++++++++++++++++++++--------------- 1 files changed, 39 insertions(+), 19 deletions(-) diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index c778620..c6a456a 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -208,7 +208,7 @@ static char *follow_link(char *link) return ERR_PTR(n); } -static int read_inode(struct inode *ino) +static int hostfs_read_inode(struct inode *ino) { char *name; int err = 0; @@ -238,6 +238,25 @@ static int read_inode(struct inode *ino) return err; } +static struct inode *hostfs_iget(struct super_block *sb) +{ + struct inode *inode; + long ret; + + inode = iget_locked(sb, 0); + if (!inode) + return ERR_PTR(-ENOMEM); + if (inode->i_state & I_NEW) { + ret = hostfs_read_inode(inode); + if (ret < 0) { + iget_failed(inode); + return ERR_PTR(ret); + } + unlock_new_inode(inode); + } + return inode; +} + int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) { /* do_statfs uses struct statfs64 internally, but the linux kernel @@ -305,17 +324,11 @@ static void hostfs_destroy_inode(struct inode *inode) kfree(HOSTFS_I(inode)); } -static void hostfs_read_inode(struct inode *inode) -{ - read_inode(inode); -} - static const struct super_operations hostfs_sbops = { .alloc_inode = hostfs_alloc_inode, .drop_inode = generic_delete_inode, .delete_inode = hostfs_delete_inode, .destroy_inode = hostfs_destroy_inode, - .read_inode = hostfs_read_inode, .statfs = hostfs_statfs, }; @@ -584,9 +597,11 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, char *name; int error, fd; - error = -ENOMEM; - inode = iget(dir->i_sb, 0); - if(inode == NULL) goto out; + inode = hostfs_iget(dir->i_sb); + if (IS_ERR(inode)) { + error = PTR_ERR(inode); + goto out; + } error = init_inode(inode, dentry); if(error) @@ -627,10 +642,11 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, char *name; int err; - err = -ENOMEM; - inode = iget(ino->i_sb, 0); - if(inode == NULL) + inode = hostfs_iget(ino->i_sb); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); goto out; + } err = init_inode(inode, dentry); if(err) @@ -748,11 +764,13 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode *inode; char *name; - int err = -ENOMEM; + int err; - inode = iget(dir->i_sb, 0); - if(inode == NULL) + inode = hostfs_iget(dir->i_sb); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); goto out; + } err = init_inode(inode, dentry); if(err) @@ -973,9 +991,11 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) sprintf(host_root_path, "%s/%s", root_ino, req_root); - root_inode = iget(sb, 0); - if(root_inode == NULL) + root_inode = hostfs_iget(sb); + if (IS_ERR(root_inode)) { + err = PTR_ERR(root_inode); goto out_free; + } err = init_inode(root_inode, NULL); if(err) @@ -991,7 +1011,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) if(sb->s_root == NULL) goto out_put; - err = read_inode(root_inode); + err = hostfs_read_inode(root_inode); if(err){ /* No iput in this case because the dput does that for us */ dput(sb->s_root); |
From: <dho...@re...> - 2007-10-01 16:06:48
|
>From dhowells Mon Oct 1 14: 11:59 2007 Return-Path: <dho...@re...> Received: from localhost.localdomain [127.0.0.1] by warthog.procyon.org.uk with IMAP (fetchmail-6.3.7) for <dhowells@localhost> (single-drop); Mon, 01 Oct 2007 14:11:59 +0100 (BST) Received: from pobox.devel.redhat.com ([unix socket]) by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA; Mon, 01 Oct 2007 09:11:50 -0400 X-Sieve: CMU Sieve 2.2 Received: from warthog.cambridge.redhat.com (devserv.devel.redhat.com [10.10.36.72]) by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l91DBnVD031197; Mon, 1 Oct 2007 09:11:49 -0400 Received: from [127.0.0.1] (helo=warthog.procyon.org.uk) by warthog.cambridge.redhat.com with esmtp (Exim 4.66 #1 (Red Hat Linux)) id 1IcL3u-0007i8-3r; Mon, 01 Oct 2007 14:11:50 +0100 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells <dho...@re...> Subject: [PATCH 29/30] IGET: Stop HPPFS from using iget() and read_inode() To: hc...@in..., vi...@ft..., tor...@os..., ak...@os... Cc: lin...@vg..., lin...@vg..., dho...@re... Date: Mon, 01 Oct 2007 14:11:50 +0100 Message-ID: <200...@wa...> In-Reply-To: <200...@wa...> References: <200...@wa...> User-Agent: StGIT/0.13 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Resent-To: use...@li... Resent-cc: jd...@ka... Resent-Date: Mon, 01 Oct 2007 17:06:33 +0100 Resent-Message-ID: <191...@re...> Resent-From: David Howells <dho...@re...> Stop the HPPFS filesystem from using iget() and read_inode(). Provide an hppfs_iget(), and call that instead of iget(). hppfs_iget() then uses iget_locked() directly and returns a proper error code instead of an inode in the event of an error. hppfs_fill_sb_common() returns any error incurred when getting the root inode instead of EINVAL. Note that the contents of hppfs_kern.c need to be examined: (*) The HPPFS inode retains a pointer to the proc dentry it is shadowing, but whilst it does appear to retain a reference to it, it doesn't appear to destroy the reference if the inode goes away. (*) hppfs_iget() should perhaps subsume init_inode() and hppfs_read_inode(). (*) It would appear that all hppfs inodes are the same inode because iget() was being called with inode number 0, which forms the lookup key. Signed-off-by: David Howells <dho...@re...> --- fs/hppfs/hppfs_kern.c | 27 ++++++++++++++++++++++----- 1 files changed, 22 insertions(+), 5 deletions(-) diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index affb741..a1e1f0f 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c @@ -155,6 +155,20 @@ static void hppfs_read_inode(struct inode *ino) ino->i_blocks = proc_ino->i_blocks; } +static struct inode *hppfs_iget(struct super_block *sb) +{ + struct inode *inode; + + inode = iget_locked(sb, 0); + if (!inode) + return ERR_PTR(-ENOMEM); + if (inode->i_state & I_NEW) { + hppfs_read_inode(inode); + unlock_new_inode(inode); + } + return inode; +} + static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, struct nameidata *nd) { @@ -190,9 +204,11 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, if(IS_ERR(proc_dentry)) return(proc_dentry); - inode = iget(ino->i_sb, 0); - if(inode == NULL) + inode = hppfs_iget(ino->i_sb); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); goto out_dput; + } err = init_inode(inode, proc_dentry); if(err) @@ -652,7 +668,6 @@ static void hppfs_destroy_inode(struct inode *inode) static const struct super_operations hppfs_sbops = { .alloc_inode = hppfs_alloc_inode, .destroy_inode = hppfs_destroy_inode, - .read_inode = hppfs_read_inode, .delete_inode = hppfs_delete_inode, .statfs = hppfs_statfs, }; @@ -745,9 +760,11 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent) sb->s_magic = HPPFS_SUPER_MAGIC; sb->s_op = &hppfs_sbops; - root_inode = iget(sb, 0); - if(root_inode == NULL) + root_inode = hppfs_iget(sb); + if (IS_ERR(root_inode)) { + err = PTR_ERR(root_inode); goto out; + } err = init_inode(root_inode, proc_sb->s_root); if(err) |
From: Miklos S. <mi...@sz...> - 2009-03-30 18:42:34
|
BCC: miko Subject: [patch 2/3] uml: fix link error from prefixing of i386 syscalls with ptregs_ References: <E1L...@po...> --text follows this line-- From: Miklos Szeredi <msz...@su...> Fix the following link error: arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x11c): undefined reference to `ptregs_fork' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x140): undefined reference to `ptregs_execve' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x2cc): undefined reference to `ptregs_iopl' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x2d8): undefined reference to `ptregs_vm86old' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x2f0): undefined reference to `ptregs_sigreturn' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x2f4): undefined reference to `ptregs_clone' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x3ac): undefined reference to `ptregs_vm86' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x3c8): undefined reference to `ptregs_rt_sigreturn' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x3fc): undefined reference to `ptregs_sigaltstack' arch/um/sys-i386/built-in.o: In function `sys_call_table': (.rodata+0x40c): undefined reference to `ptregs_vfork' This was introduced by commit 253f29a4, "x86: pass in pt_regs pointer for syscalls that need it" Signed-off-by: Miklos Szeredi <msz...@su...> --- arch/um/sys-i386/sys_call_table.S | 11 +++++++++++ 1 file changed, 11 insertions(+) Index: linux-2.6/arch/um/sys-i386/sys_call_table.S =================================================================== --- linux-2.6.orig/arch/um/sys-i386/sys_call_table.S 2009-03-27 10:57:38.000000000 +0100 +++ linux-2.6/arch/um/sys-i386/sys_call_table.S 2009-03-30 19:53:14.000000000 +0200 @@ -9,6 +9,17 @@ #define old_mmap old_mmap_i386 +#define ptregs_fork sys_fork +#define ptregs_execve sys_execve +#define ptregs_iopl sys_iopl +#define ptregs_vm86old sys_vm86old +#define ptregs_sigreturn sys_sigreturn +#define ptregs_clone sys_clone +#define ptregs_vm86 sys_vm86 +#define ptregs_rt_sigreturn sys_rt_sigreturn +#define ptregs_sigaltstack sys_sigaltstack +#define ptregs_vfork sys_vfork + .section .rodata,"a" #include "../../x86/kernel/syscall_table_32.S" |
From: Richard W. <ri...@no...> - 2012-02-12 00:21:26
|
Can you please review this patch? Thanks, //richard --- >From d8f5e7953def150bcc1e6a39dbbe589f1c68bcbd Mon Sep 17 00:00:00 2001 From: Richard Weinberger <ri...@no...> Date: Sun, 12 Feb 2012 01:12:49 +0100 Subject: [PATCH] um: Use tty_port UML's line driver has to use tty_port. Signed-off-by: Richard Weinberger <ri...@no...> --- arch/um/drivers/line.c | 212 +++++++++++--------------------------- arch/um/drivers/line.h | 13 ++- arch/um/drivers/ssl.c | 16 +++- arch/um/drivers/stdio_console.c | 14 ++- 4 files changed, 94 insertions(+), 161 deletions(-) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index c1cf220..c789748 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -19,19 +19,29 @@ static irqreturn_t line_interrupt(int irq, void *data) { struct chan *chan = data; struct line *line = chan->line; + struct tty_struct *tty; + + if (line) { + tty = tty_port_tty_get(&line->port); + chan_interrupt(&line->chan_list, &line->task, tty, irq); + tty_kref_put(tty); + } - if (line) - chan_interrupt(&line->chan_list, &line->task, line->tty, irq); return IRQ_HANDLED; } static void line_timer_cb(struct work_struct *work) { struct line *line = container_of(work, struct line, task.work); + struct tty_struct *tty; - if (!line->throttled) - chan_interrupt(&line->chan_list, &line->task, line->tty, + if (!line->throttled) { + tty = tty_port_tty_get(&line->port); + chan_interrupt(&line->chan_list, &line->task, tty, line->driver->read_irq); + + tty_kref_put(tty); + } } /* @@ -228,92 +238,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old) /* nothing */ } -static const struct { - int cmd; - char *level; - char *name; -} tty_ioctls[] = { - /* don't print these, they flood the log ... */ - { TCGETS, NULL, "TCGETS" }, - { TCSETS, NULL, "TCSETS" }, - { TCSETSW, NULL, "TCSETSW" }, - { TCFLSH, NULL, "TCFLSH" }, - { TCSBRK, NULL, "TCSBRK" }, - - /* general tty stuff */ - { TCSETSF, KERN_DEBUG, "TCSETSF" }, - { TCGETA, KERN_DEBUG, "TCGETA" }, - { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, - { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, - { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, - - /* linux-specific ones */ - { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, - { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, - { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, - { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, -}; - -int line_ioctl(struct tty_struct *tty, unsigned int cmd, - unsigned long arg) -{ - int ret; - int i; - - ret = 0; - switch(cmd) { -#ifdef TIOCGETP - case TIOCGETP: - case TIOCSETP: - case TIOCSETN: -#endif -#ifdef TIOCGETC - case TIOCGETC: - case TIOCSETC: -#endif -#ifdef TIOCGLTC - case TIOCGLTC: - case TIOCSLTC: -#endif - /* Note: these are out of date as we now have TCGETS2 etc but this - whole lot should probably go away */ - case TCGETS: - case TCSETSF: - case TCSETSW: - case TCSETS: - case TCGETA: - case TCSETAF: - case TCSETAW: - case TCSETA: - case TCXONC: - case TCFLSH: - case TIOCOUTQ: - case TIOCINQ: - case TIOCGLCKTRMIOS: - case TIOCSLCKTRMIOS: - case TIOCPKT: - case TIOCGSOFTCAR: - case TIOCSSOFTCAR: - return -ENOIOCTLCMD; -#if 0 - case TCwhatever: - /* do something */ - break; -#endif - default: - for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) - if (cmd == tty_ioctls[i].cmd) - break; - if (i == ARRAY_SIZE(tty_ioctls)) { - printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", - __func__, tty->name, cmd); - } - ret = -ENOIOCTLCMD; - break; - } - return ret; -} - void line_throttle(struct tty_struct *tty) { struct line *line = tty->driver_data; @@ -343,7 +267,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) { struct chan *chan = data; struct line *line = chan->line; - struct tty_struct *tty = line->tty; + struct tty_struct *tty = tty_port_tty_get(&line->port); int err; /* @@ -354,6 +278,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data) spin_lock(&line->lock); err = flush_buffer(line); if (err == 0) { + tty_kref_put(tty); + + spin_unlock(&line->lock); return IRQ_NONE; } else if (err < 0) { line->head = line->buffer; @@ -365,9 +292,12 @@ static irqreturn_t line_write_interrupt(int irq, void *data) return IRQ_NONE; tty_wakeup(tty); + tty_kref_put(tty); return IRQ_HANDLED; } +static const struct tty_port_operations line_port_ops; + int line_setup_irq(int fd, int input, int output, struct line *line, void *data) { const struct line_driver *driver = line->driver; @@ -404,27 +334,27 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) * first open or last close. Otherwise, open and close just return. */ -int line_open(struct line *lines, struct tty_struct *tty) +int line_open(struct tty_struct *tty, struct file *filp) { - struct line *line = &lines[tty->index]; - int err = -ENODEV; + struct line *line = tty->driver_data; + return tty_port_open(&line->port, tty, filp); +} - spin_lock(&line->count_lock); - if (!line->valid) - goto out_unlock; +int line_install(struct tty_driver *driver, struct tty_struct *tty, struct line *line) +{ + int ret = tty_init_termios(tty); - err = 0; - if (line->count++) - goto out_unlock; + if (ret) + return ret; - BUG_ON(tty->driver_data); + tty_driver_kref_get(driver); + tty->count++; tty->driver_data = line; - line->tty = tty; + driver->ttys[tty->index] = tty; - spin_unlock(&line->count_lock); - err = enable_chan(line); - if (err) /* line_close() will be called by our caller */ - return err; + ret = enable_chan(line); + if (ret) + return ret; INIT_DELAYED_WORK(&line->task, line_timer_cb); @@ -437,48 +367,36 @@ int line_open(struct line *lines, struct tty_struct *tty) &tty->winsize.ws_col); return 0; - -out_unlock: - spin_unlock(&line->count_lock); - return err; } static void unregister_winch(struct tty_struct *tty); -void line_close(struct tty_struct *tty, struct file * filp) +void line_cleanup(struct tty_struct *tty) { struct line *line = tty->driver_data; - /* - * If line_open fails (and tty->driver_data is never set), - * tty_open will call line_close. So just return in this case. - */ - if (line == NULL) - return; - - /* We ignore the error anyway! */ - flush_buffer(line); - - spin_lock(&line->count_lock); - BUG_ON(!line->valid); - - if (--line->count) - goto out_unlock; - - line->tty = NULL; - tty->driver_data = NULL; - - spin_unlock(&line->count_lock); - if (line->sigio) { unregister_winch(tty); line->sigio = 0; } - return; + tty->driver_data = NULL; +} + +void line_close(struct tty_struct *tty, struct file * filp) +{ + struct line *line = tty->driver_data; + + if (!line) + return; + + tty_port_close(&line->port, tty, filp); +} -out_unlock: - spin_unlock(&line->count_lock); +void line_hangup(struct tty_struct *tty) +{ + struct line *line = tty->driver_data; + tty_port_hangup(&line->port); } void close_lines(struct line *lines, int nlines) @@ -495,13 +413,6 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, struct line *line = &lines[n]; int err = -EINVAL; - spin_lock(&line->count_lock); - - if (line->count) { - *error_out = "Device is already open"; - goto out; - } - if (line->init_pri <= init_prio) { line->init_pri = init_prio; if (!strcmp(init, "none")) @@ -512,8 +423,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, } } err = 0; -out: - spin_unlock(&line->count_lock); + return err; } @@ -598,6 +508,7 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, struct line *line; char *end; int dev, n = 0; + struct tty_struct *tty; dev = simple_strtoul(name, &end, 0); if ((*end != '\0') || (end == name)) { @@ -612,13 +523,15 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, line = &lines[dev]; - spin_lock(&line->count_lock); + tty = tty_port_tty_get(&line->port); + if (!line->valid) CONFIG_CHUNK(str, size, n, "none", 1); - else if (line->tty == NULL) + else if (tty == NULL) CONFIG_CHUNK(str, size, n, line->init_str, 1); else n = chan_config_string(&line->chan_list, str, size, error_out); - spin_unlock(&line->count_lock); + + tty_kref_put(tty); return n; } @@ -678,8 +591,8 @@ struct tty_driver *register_lines(struct line_driver *line_driver, } for(i = 0; i < nlines; i++) { - if (!lines[i].valid) - tty_unregister_device(driver, i); + tty_port_init(&lines[i].port); + lines[i].port.ops = &line_port_ops; } mconsole_register_dev(&line_driver->mc); @@ -805,7 +718,6 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, .pid = pid, .tty = tty, .stack = stack }); - if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "winch", winch) < 0) { diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h index 63df3ca..54adfc6 100644 --- a/arch/um/drivers/line.h +++ b/arch/um/drivers/line.h @@ -31,9 +31,8 @@ struct line_driver { }; struct line { - struct tty_struct *tty; - spinlock_t count_lock; - unsigned long count; + struct tty_port port; + int valid; char *init_str; @@ -59,15 +58,17 @@ struct line { }; #define LINE_INIT(str, d) \ - { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \ - .init_str = str, \ + { .init_str = str, \ .init_pri = INIT_STATIC, \ .valid = 1, \ .lock = __SPIN_LOCK_UNLOCKED((str).lock), \ .driver = d } extern void line_close(struct tty_struct *tty, struct file * filp); -extern int line_open(struct line *lines, struct tty_struct *tty); +extern int line_open(struct tty_struct *tty, struct file *filp); +extern int line_install(struct tty_driver *driver, struct tty_struct *tty, struct line *line); +extern void line_cleanup(struct tty_struct *tty); +extern void line_hangup(struct tty_struct *tty); extern int line_setup(struct line *lines, unsigned int sizeof_lines, char *init, char **error_out); extern int line_write(struct tty_struct *tty, const unsigned char *buf, diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index 9d8c20a..89e4e75 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -92,6 +92,7 @@ static int ssl_remove(int n, char **error_out) error_out); } +#if 0 static int ssl_open(struct tty_struct *tty, struct file *filp) { int err = line_open(serial_lines, tty); @@ -103,7 +104,6 @@ static int ssl_open(struct tty_struct *tty, struct file *filp) return err; } -#if 0 static void ssl_flush_buffer(struct tty_struct *tty) { return; @@ -124,8 +124,16 @@ void ssl_hangup(struct tty_struct *tty) } #endif +static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) +{ + if (tty->index < NR_PORTS) + return line_install(driver, tty, &serial_lines[tty->index]); + else + return -ENODEV; +} + static const struct tty_operations ssl_ops = { - .open = ssl_open, + .open = line_open, .close = line_close, .write = line_write, .put_char = line_put_char, @@ -134,9 +142,11 @@ static const struct tty_operations ssl_ops = { .flush_buffer = line_flush_buffer, .flush_chars = line_flush_chars, .set_termios = line_set_termios, - .ioctl = line_ioctl, .throttle = line_throttle, .unthrottle = line_unthrottle, + .install = ssl_install, + .cleanup = line_cleanup, + .hangup = line_hangup, #if 0 .stop = ssl_stop, .start = ssl_start, diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 088776f..014f3ee 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -97,7 +97,7 @@ static int con_remove(int n, char **error_out) static int con_open(struct tty_struct *tty, struct file *filp) { - int err = line_open(vts, tty); + int err = line_open(tty, filp); if (err) printk(KERN_ERR "Failed to open console %d, err = %d\n", tty->index, err); @@ -105,6 +105,14 @@ static int con_open(struct tty_struct *tty, struct file *filp) return err; } +static int con_install(struct tty_driver *driver, struct tty_struct *tty) +{ + if (tty->index < MAX_TTYS) + return line_install(driver, tty, &vts[tty->index]); + else + return -ENODEV; +} + /* Set in an initcall, checked in an exitcall */ static int con_init_done = 0; @@ -118,9 +126,11 @@ static const struct tty_operations console_ops = { .flush_buffer = line_flush_buffer, .flush_chars = line_flush_chars, .set_termios = line_set_termios, - .ioctl = line_ioctl, .throttle = line_throttle, .unthrottle = line_unthrottle, + .cleanup = line_cleanup, + .install = con_install, + .hangup = line_hangup, }; static void uml_console_write(struct console *console, const char *string, -- 1.7.7.3 |
From: Richard W. <ri...@no...> - 2012-02-12 00:24:47
Attachments:
signature.asc
|
Whoops, I messed up the subject line. Sorry! Am 12.02.2012 01:21, schrieb Richard Weinberger: > Can you please review this patch? > > Thanks, > //richard > > --- > From d8f5e7953def150bcc1e6a39dbbe589f1c68bcbd Mon Sep 17 00:00:00 2001 > From: Richard Weinberger <ri...@no...> > Date: Sun, 12 Feb 2012 01:12:49 +0100 > Subject: [PATCH] um: Use tty_port > > UML's line driver has to use tty_port. > > Signed-off-by: Richard Weinberger <ri...@no...> > --- > arch/um/drivers/line.c | 212 +++++++++++--------------------------- > arch/um/drivers/line.h | 13 ++- > arch/um/drivers/ssl.c | 16 +++- > arch/um/drivers/stdio_console.c | 14 ++- > 4 files changed, 94 insertions(+), 161 deletions(-) > > diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c > index c1cf220..c789748 100644 > --- a/arch/um/drivers/line.c > +++ b/arch/um/drivers/line.c > @@ -19,19 +19,29 @@ static irqreturn_t line_interrupt(int irq, void *data) > { > struct chan *chan = data; > struct line *line = chan->line; > + struct tty_struct *tty; > + > + if (line) { > + tty = tty_port_tty_get(&line->port); > + chan_interrupt(&line->chan_list, &line->task, tty, irq); > + tty_kref_put(tty); > + } > > - if (line) > - chan_interrupt(&line->chan_list, &line->task, line->tty, irq); > return IRQ_HANDLED; > } > > static void line_timer_cb(struct work_struct *work) > { > struct line *line = container_of(work, struct line, task.work); > + struct tty_struct *tty; > > - if (!line->throttled) > - chan_interrupt(&line->chan_list, &line->task, line->tty, > + if (!line->throttled) { > + tty = tty_port_tty_get(&line->port); > + chan_interrupt(&line->chan_list, &line->task, tty, > line->driver->read_irq); > + > + tty_kref_put(tty); > + } > } > > /* > @@ -228,92 +238,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old) > /* nothing */ > } > > -static const struct { > - int cmd; > - char *level; > - char *name; > -} tty_ioctls[] = { > - /* don't print these, they flood the log ... */ > - { TCGETS, NULL, "TCGETS" }, > - { TCSETS, NULL, "TCSETS" }, > - { TCSETSW, NULL, "TCSETSW" }, > - { TCFLSH, NULL, "TCFLSH" }, > - { TCSBRK, NULL, "TCSBRK" }, > - > - /* general tty stuff */ > - { TCSETSF, KERN_DEBUG, "TCSETSF" }, > - { TCGETA, KERN_DEBUG, "TCGETA" }, > - { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, > - { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, > - { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, > - > - /* linux-specific ones */ > - { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, > - { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, > - { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, > - { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, > -}; > - > -int line_ioctl(struct tty_struct *tty, unsigned int cmd, > - unsigned long arg) > -{ > - int ret; > - int i; > - > - ret = 0; > - switch(cmd) { > -#ifdef TIOCGETP > - case TIOCGETP: > - case TIOCSETP: > - case TIOCSETN: > -#endif > -#ifdef TIOCGETC > - case TIOCGETC: > - case TIOCSETC: > -#endif > -#ifdef TIOCGLTC > - case TIOCGLTC: > - case TIOCSLTC: > -#endif > - /* Note: these are out of date as we now have TCGETS2 etc but this > - whole lot should probably go away */ > - case TCGETS: > - case TCSETSF: > - case TCSETSW: > - case TCSETS: > - case TCGETA: > - case TCSETAF: > - case TCSETAW: > - case TCSETA: > - case TCXONC: > - case TCFLSH: > - case TIOCOUTQ: > - case TIOCINQ: > - case TIOCGLCKTRMIOS: > - case TIOCSLCKTRMIOS: > - case TIOCPKT: > - case TIOCGSOFTCAR: > - case TIOCSSOFTCAR: > - return -ENOIOCTLCMD; > -#if 0 > - case TCwhatever: > - /* do something */ > - break; > -#endif > - default: > - for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) > - if (cmd == tty_ioctls[i].cmd) > - break; > - if (i == ARRAY_SIZE(tty_ioctls)) { > - printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", > - __func__, tty->name, cmd); > - } > - ret = -ENOIOCTLCMD; > - break; > - } > - return ret; > -} > - > void line_throttle(struct tty_struct *tty) > { > struct line *line = tty->driver_data; > @@ -343,7 +267,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) > { > struct chan *chan = data; > struct line *line = chan->line; > - struct tty_struct *tty = line->tty; > + struct tty_struct *tty = tty_port_tty_get(&line->port); > int err; > > /* > @@ -354,6 +278,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data) > spin_lock(&line->lock); > err = flush_buffer(line); > if (err == 0) { > + tty_kref_put(tty); > + > + spin_unlock(&line->lock); > return IRQ_NONE; > } else if (err < 0) { > line->head = line->buffer; > @@ -365,9 +292,12 @@ static irqreturn_t line_write_interrupt(int irq, void *data) > return IRQ_NONE; > > tty_wakeup(tty); > + tty_kref_put(tty); > return IRQ_HANDLED; > } > > +static const struct tty_port_operations line_port_ops; > + > int line_setup_irq(int fd, int input, int output, struct line *line, void *data) > { > const struct line_driver *driver = line->driver; > @@ -404,27 +334,27 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) > * first open or last close. Otherwise, open and close just return. > */ > > -int line_open(struct line *lines, struct tty_struct *tty) > +int line_open(struct tty_struct *tty, struct file *filp) > { > - struct line *line = &lines[tty->index]; > - int err = -ENODEV; > + struct line *line = tty->driver_data; > + return tty_port_open(&line->port, tty, filp); > +} > > - spin_lock(&line->count_lock); > - if (!line->valid) > - goto out_unlock; > +int line_install(struct tty_driver *driver, struct tty_struct *tty, struct line *line) > +{ > + int ret = tty_init_termios(tty); > > - err = 0; > - if (line->count++) > - goto out_unlock; > + if (ret) > + return ret; > > - BUG_ON(tty->driver_data); > + tty_driver_kref_get(driver); > + tty->count++; > tty->driver_data = line; > - line->tty = tty; > + driver->ttys[tty->index] = tty; > > - spin_unlock(&line->count_lock); > - err = enable_chan(line); > - if (err) /* line_close() will be called by our caller */ > - return err; > + ret = enable_chan(line); > + if (ret) > + return ret; > > INIT_DELAYED_WORK(&line->task, line_timer_cb); > > @@ -437,48 +367,36 @@ int line_open(struct line *lines, struct tty_struct *tty) > &tty->winsize.ws_col); > > return 0; > - > -out_unlock: > - spin_unlock(&line->count_lock); > - return err; > } > > static void unregister_winch(struct tty_struct *tty); > > -void line_close(struct tty_struct *tty, struct file * filp) > +void line_cleanup(struct tty_struct *tty) > { > struct line *line = tty->driver_data; > > - /* > - * If line_open fails (and tty->driver_data is never set), > - * tty_open will call line_close. So just return in this case. > - */ > - if (line == NULL) > - return; > - > - /* We ignore the error anyway! */ > - flush_buffer(line); > - > - spin_lock(&line->count_lock); > - BUG_ON(!line->valid); > - > - if (--line->count) > - goto out_unlock; > - > - line->tty = NULL; > - tty->driver_data = NULL; > - > - spin_unlock(&line->count_lock); > - > if (line->sigio) { > unregister_winch(tty); > line->sigio = 0; > } > > - return; > + tty->driver_data = NULL; > +} > + > +void line_close(struct tty_struct *tty, struct file * filp) > +{ > + struct line *line = tty->driver_data; > + > + if (!line) > + return; > + > + tty_port_close(&line->port, tty, filp); > +} > > -out_unlock: > - spin_unlock(&line->count_lock); > +void line_hangup(struct tty_struct *tty) > +{ > + struct line *line = tty->driver_data; > + tty_port_hangup(&line->port); > } > > void close_lines(struct line *lines, int nlines) > @@ -495,13 +413,6 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, > struct line *line = &lines[n]; > int err = -EINVAL; > > - spin_lock(&line->count_lock); > - > - if (line->count) { > - *error_out = "Device is already open"; > - goto out; > - } > - > if (line->init_pri <= init_prio) { > line->init_pri = init_prio; > if (!strcmp(init, "none")) > @@ -512,8 +423,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, > } > } > err = 0; > -out: > - spin_unlock(&line->count_lock); > + > return err; > } > > @@ -598,6 +508,7 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, > struct line *line; > char *end; > int dev, n = 0; > + struct tty_struct *tty; > > dev = simple_strtoul(name, &end, 0); > if ((*end != '\0') || (end == name)) { > @@ -612,13 +523,15 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, > > line = &lines[dev]; > > - spin_lock(&line->count_lock); > + tty = tty_port_tty_get(&line->port); > + > if (!line->valid) > CONFIG_CHUNK(str, size, n, "none", 1); > - else if (line->tty == NULL) > + else if (tty == NULL) > CONFIG_CHUNK(str, size, n, line->init_str, 1); > else n = chan_config_string(&line->chan_list, str, size, error_out); > - spin_unlock(&line->count_lock); > + > + tty_kref_put(tty); > > return n; > } > @@ -678,8 +591,8 @@ struct tty_driver *register_lines(struct line_driver *line_driver, > } > > for(i = 0; i < nlines; i++) { > - if (!lines[i].valid) > - tty_unregister_device(driver, i); > + tty_port_init(&lines[i].port); > + lines[i].port.ops = &line_port_ops; > } > > mconsole_register_dev(&line_driver->mc); > @@ -805,7 +718,6 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty, > .pid = pid, > .tty = tty, > .stack = stack }); > - > if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, > IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, > "winch", winch) < 0) { > diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h > index 63df3ca..54adfc6 100644 > --- a/arch/um/drivers/line.h > +++ b/arch/um/drivers/line.h > @@ -31,9 +31,8 @@ struct line_driver { > }; > > struct line { > - struct tty_struct *tty; > - spinlock_t count_lock; > - unsigned long count; > + struct tty_port port; > + > int valid; > > char *init_str; > @@ -59,15 +58,17 @@ struct line { > }; > > #define LINE_INIT(str, d) \ > - { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \ > - .init_str = str, \ > + { .init_str = str, \ > .init_pri = INIT_STATIC, \ > .valid = 1, \ > .lock = __SPIN_LOCK_UNLOCKED((str).lock), \ > .driver = d } > > extern void line_close(struct tty_struct *tty, struct file * filp); > -extern int line_open(struct line *lines, struct tty_struct *tty); > +extern int line_open(struct tty_struct *tty, struct file *filp); > +extern int line_install(struct tty_driver *driver, struct tty_struct *tty, struct line *line); > +extern void line_cleanup(struct tty_struct *tty); > +extern void line_hangup(struct tty_struct *tty); > extern int line_setup(struct line *lines, unsigned int sizeof_lines, > char *init, char **error_out); > extern int line_write(struct tty_struct *tty, const unsigned char *buf, > diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c > index 9d8c20a..89e4e75 100644 > --- a/arch/um/drivers/ssl.c > +++ b/arch/um/drivers/ssl.c > @@ -92,6 +92,7 @@ static int ssl_remove(int n, char **error_out) > error_out); > } > > +#if 0 > static int ssl_open(struct tty_struct *tty, struct file *filp) > { > int err = line_open(serial_lines, tty); > @@ -103,7 +104,6 @@ static int ssl_open(struct tty_struct *tty, struct file *filp) > return err; > } > > -#if 0 > static void ssl_flush_buffer(struct tty_struct *tty) > { > return; > @@ -124,8 +124,16 @@ void ssl_hangup(struct tty_struct *tty) > } > #endif > > +static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) > +{ > + if (tty->index < NR_PORTS) > + return line_install(driver, tty, &serial_lines[tty->index]); > + else > + return -ENODEV; > +} > + > static const struct tty_operations ssl_ops = { > - .open = ssl_open, > + .open = line_open, > .close = line_close, > .write = line_write, > .put_char = line_put_char, > @@ -134,9 +142,11 @@ static const struct tty_operations ssl_ops = { > .flush_buffer = line_flush_buffer, > .flush_chars = line_flush_chars, > .set_termios = line_set_termios, > - .ioctl = line_ioctl, > .throttle = line_throttle, > .unthrottle = line_unthrottle, > + .install = ssl_install, > + .cleanup = line_cleanup, > + .hangup = line_hangup, > #if 0 > .stop = ssl_stop, > .start = ssl_start, > diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c > index 088776f..014f3ee 100644 > --- a/arch/um/drivers/stdio_console.c > +++ b/arch/um/drivers/stdio_console.c > @@ -97,7 +97,7 @@ static int con_remove(int n, char **error_out) > > static int con_open(struct tty_struct *tty, struct file *filp) > { > - int err = line_open(vts, tty); > + int err = line_open(tty, filp); > if (err) > printk(KERN_ERR "Failed to open console %d, err = %d\n", > tty->index, err); > @@ -105,6 +105,14 @@ static int con_open(struct tty_struct *tty, struct file *filp) > return err; > } > > +static int con_install(struct tty_driver *driver, struct tty_struct *tty) > +{ > + if (tty->index < MAX_TTYS) > + return line_install(driver, tty, &vts[tty->index]); > + else > + return -ENODEV; > +} > + > /* Set in an initcall, checked in an exitcall */ > static int con_init_done = 0; > > @@ -118,9 +126,11 @@ static const struct tty_operations console_ops = { > .flush_buffer = line_flush_buffer, > .flush_chars = line_flush_chars, > .set_termios = line_set_termios, > - .ioctl = line_ioctl, > .throttle = line_throttle, > .unthrottle = line_unthrottle, > + .cleanup = line_cleanup, > + .install = con_install, > + .hangup = line_hangup, > }; > > static void uml_console_write(struct console *console, const char *string, |
From: Jiri S. <js...@su...> - 2012-02-12 13:01:19
|
On 02/12/2012 01:24 AM, Richard Weinberger wrote: >> @@ -228,92 +238,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old) >> /* nothing */ >> } >> >> -static const struct { >> - int cmd; >> - char *level; >> - char *name; >> -} tty_ioctls[] = { >> - /* don't print these, they flood the log ... */ >> - { TCGETS, NULL, "TCGETS" }, >> - { TCSETS, NULL, "TCSETS" }, >> - { TCSETSW, NULL, "TCSETSW" }, >> - { TCFLSH, NULL, "TCFLSH" }, >> - { TCSBRK, NULL, "TCSBRK" }, >> - >> - /* general tty stuff */ >> - { TCSETSF, KERN_DEBUG, "TCSETSF" }, >> - { TCGETA, KERN_DEBUG, "TCGETA" }, >> - { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, >> - { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, >> - { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, >> - >> - /* linux-specific ones */ >> - { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, >> - { KDGKBMODE, KERN_INFO, "KDGKBMODE" }, >> - { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" }, >> - { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" }, >> -}; >> - >> -int line_ioctl(struct tty_struct *tty, unsigned int cmd, >> - unsigned long arg) >> -{ >> - int ret; >> - int i; >> - >> - ret = 0; >> - switch(cmd) { >> -#ifdef TIOCGETP >> - case TIOCGETP: >> - case TIOCSETP: >> - case TIOCSETN: >> -#endif >> -#ifdef TIOCGETC >> - case TIOCGETC: >> - case TIOCSETC: >> -#endif >> -#ifdef TIOCGLTC >> - case TIOCGLTC: >> - case TIOCSLTC: >> -#endif >> - /* Note: these are out of date as we now have TCGETS2 etc but this >> - whole lot should probably go away */ >> - case TCGETS: >> - case TCSETSF: >> - case TCSETSW: >> - case TCSETS: >> - case TCGETA: >> - case TCSETAF: >> - case TCSETAW: >> - case TCSETA: >> - case TCXONC: >> - case TCFLSH: >> - case TIOCOUTQ: >> - case TIOCINQ: >> - case TIOCGLCKTRMIOS: >> - case TIOCSLCKTRMIOS: >> - case TIOCPKT: >> - case TIOCGSOFTCAR: >> - case TIOCSSOFTCAR: >> - return -ENOIOCTLCMD; >> -#if 0 >> - case TCwhatever: >> - /* do something */ >> - break; >> -#endif >> - default: >> - for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) >> - if (cmd == tty_ioctls[i].cmd) >> - break; >> - if (i == ARRAY_SIZE(tty_ioctls)) { >> - printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", >> - __func__, tty->name, cmd); >> - } >> - ret = -ENOIOCTLCMD; >> - break; >> - } >> - return ret; >> -} >> - >> void line_throttle(struct tty_struct *tty) >> { >> struct line *line = tty->driver_data; >> @@ -343,7 +267,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) >> { >> struct chan *chan = data; >> struct line *line = chan->line; >> - struct tty_struct *tty = line->tty; >> + struct tty_struct *tty = tty_port_tty_get(&line->port); >> int err; >> >> /* >> @@ -354,6 +278,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data) >> spin_lock(&line->lock); >> err = flush_buffer(line); >> if (err == 0) { >> + tty_kref_put(tty); >> + >> + spin_unlock(&line->lock); This and the ioctl change above fullfils the subject of the patch in no way. Do this fix and the cleanup above separately, please. >> @@ -404,27 +334,27 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) >> * first open or last close. Otherwise, open and close just return. >> */ >> >> -int line_open(struct line *lines, struct tty_struct *tty) >> +int line_open(struct tty_struct *tty, struct file *filp) >> { >> - struct line *line = &lines[tty->index]; >> - int err = -ENODEV; >> + struct line *line = tty->driver_data; >> + return tty_port_open(&line->port, tty, filp); >> +} >> >> - spin_lock(&line->count_lock); >> - if (!line->valid) >> - goto out_unlock; >> +int line_install(struct tty_driver *driver, struct tty_struct *tty, struct line *line) As it stands, it should be tty_port->ops->activate, not tty->ops->install. Yes, you can still set driver_data and check for multiple opens in install. Then use also tty_standard_install. >> +{ >> + int ret = tty_init_termios(tty); >> >> - err = 0; >> - if (line->count++) >> - goto out_unlock; >> + if (ret) >> + return ret; >> >> - BUG_ON(tty->driver_data); >> + tty_driver_kref_get(driver); >> + tty->count++; >> tty->driver_data = line; >> - line->tty = tty; >> + driver->ttys[tty->index] = tty; >> >> - spin_unlock(&line->count_lock); >> - err = enable_chan(line); >> - if (err) /* line_close() will be called by our caller */ >> - return err; >> + ret = enable_chan(line); >> + if (ret) >> + return ret; >> >> INIT_DELAYED_WORK(&line->task, line_timer_cb); >> >> @@ -437,48 +367,36 @@ int line_open(struct line *lines, struct tty_struct *tty) >> &tty->winsize.ws_col); >> >> return 0; >> - >> -out_unlock: >> - spin_unlock(&line->count_lock); >> - return err; >> } ... >> +void line_close(struct tty_struct *tty, struct file * filp) >> +{ >> + struct line *line = tty->driver_data; >> + >> + if (!line) >> + return; Unless you set tty->driver_data to NULL somewhere, this can never happen. If you do, why -- this tends to be racy? >> + tty_port_close(&line->port, tty, filp); >> +} ... >> --- a/arch/um/drivers/ssl.c >> +++ b/arch/um/drivers/ssl.c >> @@ -92,6 +92,7 @@ static int ssl_remove(int n, char **error_out) >> error_out); >> } >> >> +#if 0 Hmm, remove unused code instead. >> static int ssl_open(struct tty_struct *tty, struct file *filp) >> { >> int err = line_open(serial_lines, tty); ... >> @@ -124,8 +124,16 @@ void ssl_hangup(struct tty_struct *tty) >> } >> #endif >> >> +static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) >> +{ >> + if (tty->index < NR_PORTS) Do you register more than NR_PORTS when allocating tty_driver? If not, this test is always true. But presumably you won't need this hook anyway. >> + return line_install(driver, tty, &serial_lines[tty->index]); >> + else >> + return -ENODEV; >> +} thanks, -- js suse labs |
From: Richard W. <ri...@no...> - 2012-02-12 13:12:27
Attachments:
signature.asc
|
Am 12.02.2012 14:01, schrieb Jiri Slaby: > This and the ioctl change above fullfils the subject of the patch in no > way. Do this fix and the cleanup above separately, please. Fair point. > >>> @@ -404,27 +334,27 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) >>> * first open or last close. Otherwise, open and close just return. >>> */ >>> >>> -int line_open(struct line *lines, struct tty_struct *tty) >>> +int line_open(struct tty_struct *tty, struct file *filp) >>> { >>> - struct line *line = &lines[tty->index]; >>> - int err = -ENODEV; >>> + struct line *line = tty->driver_data; >>> + return tty_port_open(&line->port, tty, filp); >>> +} >>> >>> - spin_lock(&line->count_lock); >>> - if (!line->valid) >>> - goto out_unlock; >>> +int line_install(struct tty_driver *driver, struct tty_struct *tty, struct line *line) > > As it stands, it should be tty_port->ops->activate, not > tty->ops->install. Yes, you can still set driver_data and check for > multiple opens in install. Then use also tty_standard_install. Okay. >>> +{ >>> + int ret = tty_init_termios(tty); >>> >>> - err = 0; >>> - if (line->count++) >>> - goto out_unlock; >>> + if (ret) >>> + return ret; >>> >>> - BUG_ON(tty->driver_data); >>> + tty_driver_kref_get(driver); >>> + tty->count++; >>> tty->driver_data = line; >>> - line->tty = tty; >>> + driver->ttys[tty->index] = tty; >>> >>> - spin_unlock(&line->count_lock); >>> - err = enable_chan(line); >>> - if (err) /* line_close() will be called by our caller */ >>> - return err; >>> + ret = enable_chan(line); >>> + if (ret) >>> + return ret; >>> >>> INIT_DELAYED_WORK(&line->task, line_timer_cb); >>> >>> @@ -437,48 +367,36 @@ int line_open(struct line *lines, struct tty_struct *tty) >>> &tty->winsize.ws_col); >>> >>> return 0; >>> - >>> -out_unlock: >>> - spin_unlock(&line->count_lock); >>> - return err; >>> } > ... >>> +void line_close(struct tty_struct *tty, struct file * filp) >>> +{ >>> + struct line *line = tty->driver_data; >>> + >>> + if (!line) >>> + return; > > Unless you set tty->driver_data to NULL somewhere, this can never > happen. If you do, why -- this tends to be racy? The old driver set tty->driver_data to NULL. I guess we can remove it. >>> + tty_port_close(&line->port, tty, filp); >>> +} > ... >>> --- a/arch/um/drivers/ssl.c >>> +++ b/arch/um/drivers/ssl.c >>> @@ -92,6 +92,7 @@ static int ssl_remove(int n, char **error_out) >>> error_out); >>> } >>> >>> +#if 0 > > Hmm, remove unused code instead. Will do. >>> static int ssl_open(struct tty_struct *tty, struct file *filp) >>> { >>> int err = line_open(serial_lines, tty); > ... >>> @@ -124,8 +124,16 @@ void ssl_hangup(struct tty_struct *tty) >>> } >>> #endif >>> >>> +static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) >>> +{ >>> + if (tty->index < NR_PORTS) > > Do you register more than NR_PORTS when allocating tty_driver? If not, > this test is always true. But presumably you won't need this hook anyway. Okay. >>> + return line_install(driver, tty, &serial_lines[tty->index]); >>> + else >>> + return -ENODEV; >>> +} > > thanks, Thanks, //richard |
From: Al V. <viro@ZenIV.linux.org.uk> - 2012-02-12 01:02:22
|
On Sun, Feb 12, 2012 at 01:21:10AM +0100, Richard Weinberger wrote: Not a full review by any means, but... > +++ b/arch/um/drivers/line.c > @@ -19,19 +19,29 @@ static irqreturn_t line_interrupt(int irq, void *data) > { > struct chan *chan = data; > struct line *line = chan->line; > + struct tty_struct *tty; > + > + if (line) { > + tty = tty_port_tty_get(&line->port); > + chan_interrupt(&line->chan_list, &line->task, tty, irq); > + tty_kref_put(tty); > + } > > - if (line) > - chan_interrupt(&line->chan_list, &line->task, line->tty, irq); > return IRQ_HANDLED; > } Is tty_kref_put() safe in interrupt? Here it seems to be OK, but in other callers... More or less at random: drivers/tty/serial/lantiq.c has it called from lqasc_rx_int(). It seems to be possible to have it end up calling ->ops->shutdown() and in this case that'd be lqasc_shutdown(). Which does a bunch of free_irq(), including the ->rx_irq, i.e. the one we have it called from. Alan? > @@ -495,13 +413,6 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, > struct line *line = &lines[n]; > int err = -EINVAL; > > - spin_lock(&line->count_lock); > - > - if (line->count) { > - *error_out = "Device is already open"; > - goto out; > - } ... and similar in line_open() - just what happens if you try to reconfigure an opened one? > @@ -612,13 +523,15 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str, > > line = &lines[dev]; > > - spin_lock(&line->count_lock); > + tty = tty_port_tty_get(&line->port); > + > if (!line->valid) > CONFIG_CHUNK(str, size, n, "none", 1); > - else if (line->tty == NULL) > + else if (tty == NULL) > CONFIG_CHUNK(str, size, n, line->init_str, 1); > else n = chan_config_string(&line->chan_list, str, size, error_out); > - spin_unlock(&line->count_lock); > + > + tty_kref_put(tty); again, where's the exclusion with config changes? |
From: Jiri S. <js...@su...> - 2012-02-12 12:40:59
|
On 02/12/2012 02:02 AM, Al Viro wrote: > On Sun, Feb 12, 2012 at 01:21:10AM +0100, Richard Weinberger wrote: >> +++ b/arch/um/drivers/line.c >> @@ -19,19 +19,29 @@ static irqreturn_t line_interrupt(int irq, void *data) >> { >> struct chan *chan = data; >> struct line *line = chan->line; >> + struct tty_struct *tty; >> + >> + if (line) { >> + tty = tty_port_tty_get(&line->port); >> + chan_interrupt(&line->chan_list, &line->task, tty, irq); >> + tty_kref_put(tty); >> + } >> >> - if (line) >> - chan_interrupt(&line->chan_list, &line->task, line->tty, irq); >> return IRQ_HANDLED; >> } > > Is tty_kref_put() safe in interrupt? Here it seems to be OK, but in other > callers... More or less at random: drivers/tty/serial/lantiq.c has it > called from lqasc_rx_int(). It seems to be possible to have it end up > calling ->ops->shutdown() and in this case that'd be lqasc_shutdown(). > Which does a bunch of free_irq(), including the ->rx_irq, i.e. the one > we have it called from. Alan? I'm not Alan, but will reply anyway. Yes, it is safe (unless the driver does something tricky). In the driver you mention, this is uart_ops, called from tty_port_operations' ->shutdown. And that's a different from tty_operations' ->shutdown. Yes, there are: * tty->ops * tty_port->ops * uart_port->ops uart_port->ops->shutdown is supposed to tear down interrupts like in lantiq.c. It is called from tty_port->ops->shutdown. And that one is allowed to be called only from user context (tty->ops->close and tty->ops->hangup). thanks, -- js suse labs |
From: Al V. <viro@ZenIV.linux.org.uk> - 2012-02-12 19:06:28
|
On Sun, Feb 12, 2012 at 01:40:47PM +0100, Jiri Slaby wrote: > > Is tty_kref_put() safe in interrupt? Here it seems to be OK, but in other > > callers... More or less at random: drivers/tty/serial/lantiq.c has it > > called from lqasc_rx_int(). It seems to be possible to have it end up > > calling ->ops->shutdown() and in this case that'd be lqasc_shutdown(). > > Which does a bunch of free_irq(), including the ->rx_irq, i.e. the one > > we have it called from. Alan? > > I'm not Alan, but will reply anyway. Yes, it is safe (unless the driver > does something tricky). In the driver you mention, this is uart_ops, > called from tty_port_operations' ->shutdown. And that's a different from > tty_operations' ->shutdown. > > Yes, there are: > * tty->ops > * tty_port->ops > * uart_port->ops > > uart_port->ops->shutdown is supposed to tear down interrupts like in > lantiq.c. It is called from tty_port->ops->shutdown. And that one is > allowed to be called only from user context (tty->ops->close and > tty->ops->hangup). Yecchhh... If I'm reading (and grepping) it right, there are only two non-default instance of tty_operations ->shutdown() - pty and vt ones. Lovely... And while we are at it, vt instance is definitely not safe from interrupts - calls console_lock(). Not that it was relevant in this case... It's probably too late in this case, but I would've called that method ->sync_cleanup(). Assuming I'm not misreading its intent and history... |
From: Jiri S. <js...@su...> - 2012-02-13 09:40:23
|
On 02/12/2012 08:06 PM, Al Viro wrote: > Yecchhh... If I'm reading (and grepping) it right, there are only two > non-default instance of tty_operations ->shutdown() - pty and vt ones. > Lovely... And while we are at it, vt instance is definitely not safe > from interrupts - calls console_lock(). Not that it was relevant in > this case... Thanks for looking into that. I was too lazy to do that on Sunday. You're right that it may cause problems. Fortunately vt doesn't refcount ttys. Hence con_shutdown can be called only from release_tty (close path) in the user context. Adding to my TODO list, unless somebody beats me to fix it. thanks, -- js suse labs |
From: Al V. <viro@ZenIV.linux.org.uk> - 2012-02-12 19:11:45
|
On Sun, Feb 12, 2012 at 01:21:10AM +0100, Richard Weinberger wrote: > @@ -343,7 +267,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) > { > struct chan *chan = data; > struct line *line = chan->line; > - struct tty_struct *tty = line->tty; > + struct tty_struct *tty = tty_port_tty_get(&line->port); > int err; > > /* > @@ -354,6 +278,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data) > spin_lock(&line->lock); > err = flush_buffer(line); > if (err == 0) { > + tty_kref_put(tty); > + > + spin_unlock(&line->lock); > return IRQ_NONE; > } else if (err < 0) { > line->head = line->buffer; > @@ -365,9 +292,12 @@ static irqreturn_t line_write_interrupt(int irq, void *data) > return IRQ_NONE; > > tty_wakeup(tty); > + tty_kref_put(tty); > return IRQ_HANDLED; > } That, BTW, smells ugly. Note that return before the last one has no tty_kref_put() for a very good reason - it's under if (!tty). And just as line->tty, port->tty can become NULL, so tty_port_tty_get() can, indeed, return NULL here. Which makes the first tty_kref_put() oopsable... |
From: Jiri S. <js...@su...> - 2012-02-13 09:16:06
|
On 02/12/2012 08:11 PM, Al Viro wrote: > On Sun, Feb 12, 2012 at 01:21:10AM +0100, Richard Weinberger wrote: > >> @@ -343,7 +267,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) >> { >> struct chan *chan = data; >> struct line *line = chan->line; >> - struct tty_struct *tty = line->tty; >> + struct tty_struct *tty = tty_port_tty_get(&line->port); >> int err; >> >> /* >> @@ -354,6 +278,9 @@ static irqreturn_t line_write_interrupt(int irq, void *data) >> spin_lock(&line->lock); >> err = flush_buffer(line); >> if (err == 0) { >> + tty_kref_put(tty); >> + >> + spin_unlock(&line->lock); >> return IRQ_NONE; >> } else if (err < 0) { >> line->head = line->buffer; >> @@ -365,9 +292,12 @@ static irqreturn_t line_write_interrupt(int irq, void *data) >> return IRQ_NONE; >> >> tty_wakeup(tty); >> + tty_kref_put(tty); >> return IRQ_HANDLED; >> } > > That, BTW, smells ugly. Note that return before the last one has no > tty_kref_put() for a very good reason - it's under if (!tty). And > just as line->tty, port->tty can become NULL, so tty_port_tty_get() > can, indeed, return NULL here. Which makes the first tty_kref_put() > oopsable... Nope, it is allowed to call tty_kref_put(NULL). regards, -- js suse labs |
From: Richard W. <ri...@no...> - 2016-01-25 22:24:41
|
Last few months I was very busy and now I have the mess, UML allmod/yesconfig does not build at all. This large and boring patch series fixes a lot of drivers which cannot work/build on UML. Fixes are grouped by subsystem such that maintainers can review/pickup them. Thanks, //richard [PATCH 01/22] power: reset: Fix dependencies for !HAS_IOMEM archs [PATCH 02/22] phy: Fix dependencies for !HAS_IOMEM archs [PATCH 03/22] scsi: Fix dependencies for !HAS_IOMEM and !HAS_DMA [PATCH 04/22] staging: iio: Fix dependencies for !HAS_IOMEM archs [PATCH 05/22] hw_random: Fix dependencies for !HAS_IOMEM archs [PATCH 06/22] iio: adc: Fix dependencies for !HAS_IOMEM archs [PATCH 07/22] fpga: Fix dependencies for !HAS_IOMEM archs [PATCH 08/22] hwtracing: Fix dependencies for !HAS_IOMEM archs [PATCH 09/22] leds: Fix dependencies for !HAS_IOMEM archs [PATCH 10/22] mailbox: Fix dependencies for !HAS_IOMEM archs [PATCH 11/22] mtd: Fix dependencies for !HAS_IOMEM archs [PATCH 12/22] nvmem: Fix dependencies for !HAS_IOMEM archs [PATCH 13/22] net: Fix dependencies for !HAS_IOMEM archs [PATCH 14/22] pwm: Fix dependencies for !HAS_IOMEM archs [PATCH 15/22] watchdog: Fix dependencies for !HAS_IOMEM archs [PATCH 16/22] iio: imu: Fix dependencies for !HAS_IOMEM archs [PATCH 17/22] media: Fix dependencies for !HAS_IOMEM archs [PATCH 18/22] irqchip: Fix dependencies for !HAS_IOMEM archs [PATCH 19/22] thermal: Fix dependencies for !HAS_IOMEM archs [PATCH 20/22] clocksource: Fix dependencies for !HAS_IOMEM archs [PATCH 21/22] mtd: cs553x: Fix dependencies for !HAS_IOMEM archs [PATCH 22/22] um: Export pm_power_off |
From: Richard W. <ri...@no...> - 2016-01-25 22:24:43
|
Not every arch has io memory. So, unbreak the build by fixing the dependencies. Signed-off-by: Richard Weinberger <ri...@no...> --- drivers/phy/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index e7e117d..ddfbaf9 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -33,6 +33,7 @@ config ARMADA375_USBCLUSTER_PHY def_bool y depends on MACH_ARMADA_375 || COMPILE_TEST depends on OF + depends on HAS_IOMEM select GENERIC_PHY config PHY_DM816X_USB @@ -128,6 +129,7 @@ config PHY_RCAR_GEN3_USB2 config OMAP_CONTROL_PHY tristate "OMAP CONTROL PHY Driver" depends on ARCH_OMAP2PLUS || COMPILE_TEST + depends on HAS_IOMEM help Enable this to add support for the PHY part present in the control module. This driver has API to power on the USB2 PHY and to write to @@ -224,6 +226,7 @@ config PHY_MT65XX_USB3 config PHY_HI6220_USB tristate "hi6220 USB PHY support" + depends on HAS_IOMEM select GENERIC_PHY select MFD_SYSCON help @@ -400,6 +403,7 @@ config PHY_BRCMSTB_SATA config PHY_CYGNUS_PCIE tristate "Broadcom Cygnus PCIe PHY driver" depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST) + depends on HAS_IOMEM select GENERIC_PHY default ARCH_BCM_CYGNUS help -- 1.8.4.5 |
From: Richard W. <ri...@no...> - 2016-01-25 22:24:44
|
Not every arch has io or DMA memory. So, unbreak the build by fixing the dependencies. Signed-off-by: Richard Weinberger <ri...@no...> --- drivers/scsi/hisi_sas/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig index 37a0c71..f9157f4 100644 --- a/drivers/scsi/hisi_sas/Kconfig +++ b/drivers/scsi/hisi_sas/Kconfig @@ -2,5 +2,6 @@ config SCSI_HISI_SAS tristate "HiSilicon SAS" select SCSI_SAS_LIBSAS select BLK_DEV_INTEGRITY + depends on HAS_IOMEM && HAS_DMA help This driver supports HiSilicon's SAS HBA -- 1.8.4.5 |
From: Richard W. <ri...@no...> - 2016-01-25 22:24:53
|
Not every arch has io memory. So, unbreak the build by fixing the dependencies. Signed-off-by: Richard Weinberger <ri...@no...> --- drivers/hwtracing/intel_th/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hwtracing/intel_th/Kconfig b/drivers/hwtracing/intel_th/Kconfig index b7a9073..467dae9 100644 --- a/drivers/hwtracing/intel_th/Kconfig +++ b/drivers/hwtracing/intel_th/Kconfig @@ -1,5 +1,6 @@ config INTEL_TH tristate "Intel(R) Trace Hub controller" + depends on HAS_IOMEM help Intel(R) Trace Hub (TH) is a set of hardware blocks (subdevices) that produce, switch and output trace data from multiple hardware and -- 1.8.4.5 |