* [PATCH 02/10] block layer: add partial mappings support to bio_map_user
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: axboe, James.Bottomley; +Cc: linux-scsi
This is the updated patch for partial mappings support.
- bio_map_user_iov always allows partial mappings.
- The two users (blk_rq_map_user and blk_rq_map_user_iov) will fails
if the bio is partially mapped.
- Added a length argument to blk_rq_map_user_iov in order to avoid
including sg.h in ll_rw_blk.c for struct sg_iovec.
This is a resend:
http://marc.theaimsgroup.com/?l=linux-scsi&m=114086655400806&w=2
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
block/ll_rw_blk.c | 29 ++++++++++++++++++-----------
block/scsi_ioctl.c | 3 ++-
fs/bio.c | 14 +-------------
include/linux/blkdev.h | 3 ++-
4 files changed, 23 insertions(+), 26 deletions(-)
d43dcc5c747b5896c795e1fe1f8a6d5df525daa6
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 03d9c82..6849859 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2291,19 +2291,20 @@ int blk_rq_map_user(request_queue_t *q,
else
bio = bio_copy_user(q, uaddr, len, reading);
- if (!IS_ERR(bio)) {
- rq->bio = rq->biotail = bio;
- blk_rq_bio_prep(q, rq, bio);
+ if (IS_ERR(bio))
+ return PTR_ERR(bio);
- rq->buffer = rq->data = NULL;
- rq->data_len = len;
- return 0;
+ if (bio->bi_size != len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio);
+ return -EINVAL;
}
- /*
- * bio is the err-ptr
- */
- return PTR_ERR(bio);
+ rq->bio = rq->biotail = bio;
+ blk_rq_bio_prep(q, rq, bio);
+ rq->buffer = rq->data = NULL;
+ rq->data_len = len;
+ return 0;
}
EXPORT_SYMBOL(blk_rq_map_user);
@@ -2329,7 +2330,7 @@ EXPORT_SYMBOL(blk_rq_map_user);
* unmapping.
*/
int blk_rq_map_user_iov(request_queue_t *q, struct request *rq,
- struct sg_iovec *iov, int iov_count)
+ struct sg_iovec *iov, int iov_count, unsigned int len)
{
struct bio *bio;
@@ -2343,6 +2344,12 @@ int blk_rq_map_user_iov(request_queue_t
if (IS_ERR(bio))
return PTR_ERR(bio);
+ if (bio->bi_size != len) {
+ bio_endio(bio, bio->bi_size, 0);
+ bio_unmap_user(bio);
+ return -EINVAL;
+ }
+
rq->bio = rq->biotail = bio;
blk_rq_bio_prep(q, rq, bio);
rq->buffer = rq->data = NULL;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 24f7af9..ef9900d 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -274,7 +274,8 @@ static int sg_io(struct file *file, requ
goto out;
}
- ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count);
+ ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
+ hdr->dxfer_len);
kfree(iov);
} else if (hdr->dxfer_len)
ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);
diff --git a/fs/bio.c b/fs/bio.c
index d8259d9..f51a873 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -749,7 +749,6 @@ struct bio *bio_map_user_iov(request_que
int write_to_vm)
{
struct bio *bio;
- int len = 0, i;
bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm);
@@ -764,18 +763,7 @@ struct bio *bio_map_user_iov(request_que
*/
bio_get(bio);
- for (i = 0; i < iov_count; i++)
- len += iov[i].iov_len;
-
- if (bio->bi_size == len)
- return bio;
-
- /*
- * don't support partial mappings
- */
- bio_endio(bio, bio->bi_size, 0);
- bio_unmap_user(bio);
- return ERR_PTR(-EINVAL);
+ return bio;
}
static void __bio_unmap_user(struct bio *bio)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 860e7a4..619ef1d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -611,7 +611,8 @@ extern void blk_queue_activity_fn(reques
extern int blk_rq_map_user(request_queue_t *, struct request *, void __user *, unsigned int);
extern int blk_rq_unmap_user(struct bio *, unsigned int);
extern int blk_rq_map_kern(request_queue_t *, struct request *, void *, unsigned int, gfp_t);
-extern int blk_rq_map_user_iov(request_queue_t *, struct request *, struct sg_iovec *, int);
+extern int blk_rq_map_user_iov(request_queue_t *, struct request *,
+ struct sg_iovec *, int, unsigned int);
extern int blk_execute_rq(request_queue_t *, struct gendisk *,
struct request *, int);
extern void blk_execute_rq_nowait(request_queue_t *, struct gendisk *,
--
1.1.5
^ permalink raw reply related
* [PATCH 00/10] scsi tgt: updates (repost)
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley, axboe; +Cc: linux-scsi
This is the repost of the patches to synchronize the scsi-target-2.6
git tree with the latest code in the tgt subversion repository.
Jens, can you take a look at the block layer patches please?
^ permalink raw reply
* [PATCH 10/10] scsi tgt: add NET dependence to Kconfig
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
> From: "Jun'ichi Nomura" <j-nomura@ce.jp.nec.com>:
scsi_tgt_if.c depends on CONFIG_NET for using netlink.
So it would be nice if the Kconfig entry checks it.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
731f4924dd33579ffa5ff45ad03b7b7e933f728b
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d09c792..5b5eeb4 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -29,7 +29,7 @@ config SCSI
config SCSI_TGT
tristate "SCSI target support"
- depends on SCSI && EXPERIMENTAL
+ depends on SCSI && NET && EXPERIMENTAL
---help---
If you want to use SCSI target mode drivers enable this option.
If you choose M, the module will be called scsi_tgt.
--
1.1.5
^ permalink raw reply related
* [PATCH 03/10] scsi tgt: use the original bio_map_user interface
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
Return to the original bio_map_user interface.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/scsi_tgt_lib.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
2c78c6353dc183a16ef3e12b9c5618dd5b89679c
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 8746236..941dd64 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -315,7 +315,7 @@ static int scsi_map_user_pages(struct sc
while (len > 0) {
dprintk("%lx %u\n", (unsigned long) uaddr, len);
- bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw, 1);
+ bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw);
if (IS_ERR(bio)) {
err = PTR_ERR(bio);
dprintk("fail to map %lx %u %d %x\n",
--
1.1.5
^ permalink raw reply related
* [PATCH 07/10] scsi tgt: remove blk_queue_end_tag
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
Remove blk_queue_end_tag() in scsi_host_put_command() because tgt
doesn't use the elevator code.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/scsi.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
fd45c05acbc00cd21fa7c82f6aed5a5ef3e5b98a
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 3cf02b1..9c22465 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -352,8 +352,6 @@ void scsi_host_put_command(struct Scsi_H
spin_unlock(&shost->free_list_lock);
spin_lock(q->queue_lock);
- if (blk_rq_tagged(rq))
- blk_queue_end_tag(q, rq);
__blk_put_request(q, rq);
spin_unlock_irqrestore(q->queue_lock, flags);
--
1.1.5
^ permalink raw reply related
* [PATCH 06/10] scsi tgt: fix double lock in scsi_uspace_request_fn
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
Fix double lock in scsi_uspace_request_fn.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/scsi_tgt_lib.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
1ddfd113a764450e7998cc16dd07dcc37077b05b
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 8746236..5d76078 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -136,7 +136,7 @@ requeue:
spin_lock_irq(q->queue_lock);
/* need to track cnts and plug */
blk_requeue_request(q, rq);
- spin_lock_irq(q->queue_lock);
+ spin_unlock_irq(q->queue_lock);
}
/**
--
1.1.5
^ permalink raw reply related
* [PATCH 08/10] scsi tgt: replace the elevator code
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
tgt uses the elevator code to send SCSI commands to the user-space
daemon (q->request_fn sends netlink packets including commands).
This patch replaces the elevator code with a simple list.
This is mainly because tgt also needs to send TMF requests to the
user-space daemon (the daemon does all the SCSI state machine
stuff). tgt must send SCSI commands and TMF requests in an exact order
so that it would be preferable to use a single queue (per host) for
both. To uses the elevator code for TMF requests, tgt needs to
allocate request structures for them. That's wasteful because request
structures is useless for TMF requests, which don't perform any I/Os.
We basically have a netdev queue of events to send to userspace so by
using the request_queue and netdev queue we are basically double
queueing and wasting resources and it is affecting performance
We like to use shared memory stuff between kernel and user spaces
instead of netlink in the future. These queues would go away.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/scsi_tgt_lib.c | 180 ++++++++++++++++++++++++++++++------------
drivers/scsi/scsi_tgt_priv.h | 4 -
2 files changed, 129 insertions(+), 55 deletions(-)
c4bb05742e1834d664a7d8e721ecea71d42fd7f7
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 274d929..2cbc749 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -20,7 +20,7 @@
* 02110-1301 USA
*/
#include <linux/blkdev.h>
-#include <linux/elevator.h>
+#include <linux/hash.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <scsi/scsi.h>
@@ -46,6 +46,24 @@ struct scsi_tgt_cmd {
struct bio_list xfer_done_list;
struct bio_list xfer_list;
struct scsi_lun *lun;
+
+ struct list_head hash_list;
+ struct request *rq;
+};
+
+#define TGT_HASH_ORDER 4
+#define cmd_hashfn(cid) hash_long((cid), TGT_HASH_ORDER)
+
+struct scsi_tgt_queuedata {
+ struct Scsi_Host *shost;
+ struct list_head cmd_hash[1 << TGT_HASH_ORDER];
+ spinlock_t cmd_hash_lock;
+
+ struct work_struct uspace_send_work;
+
+ spinlock_t cmd_req_lock;
+ struct mutex cmd_req_mutex;
+ struct list_head cmd_req;
};
static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd)
@@ -68,9 +86,16 @@ static void scsi_tgt_cmd_destroy(void *d
{
struct scsi_cmnd *cmd = data;
struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data;
+ struct scsi_tgt_queuedata *qdata = cmd->request->q->queuedata;
+ unsigned long flags;
dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction,
rq_data_dir(cmd->request));
+
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+ list_del(&tcmd->hash_list);
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
+
/*
* We must set rq->flags here because bio_map_user and
* blk_rq_bio_prep ruined ti.
@@ -88,55 +113,84 @@ static void scsi_tgt_cmd_destroy(void *d
static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd)
{
+ struct scsi_tgt_queuedata *qdata = rq->q->queuedata;
+ unsigned long flags;
+ struct list_head *head;
+ static u32 tag = 0;
+
tcmd->lun = rq->end_io_data;
bio_list_init(&tcmd->xfer_list);
bio_list_init(&tcmd->xfer_done_list);
-}
-
-static int scsi_uspace_prep_fn(struct request_queue *q, struct request *rq)
-{
- struct scsi_tgt_cmd *tcmd;
- tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC);
- if (!tcmd)
- return BLKPREP_DEFER;
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+ rq->tag = tag++;
+ head = &qdata->cmd_hash[cmd_hashfn(rq->tag)];
+ list_add(&tcmd->hash_list, head);
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
- init_scsi_tgt_cmd(rq, tcmd);
+ tcmd->rq = rq;
rq->end_io_data = tcmd;
rq->flags |= REQ_DONTPREP;
- return BLKPREP_OK;
}
-static void scsi_uspace_request_fn(struct request_queue *q)
+static void scsi_tgt_uspace_send_fn(void *data)
{
+ struct request_queue *q = data;
+ struct scsi_tgt_queuedata *qdata = q->queuedata;
struct request *rq;
struct scsi_cmnd *cmd;
struct scsi_tgt_cmd *tcmd;
+ unsigned long flags;
+ int err;
- /*
- * TODO: just send everthing in the queue to userspace in
- * one vector instead of multiple calls
- */
- while ((rq = elv_next_request(q)) != NULL) {
- cmd = rq->special;
- tcmd = rq->end_io_data;
+retry:
+ err = 0;
+ if (list_empty(&qdata->cmd_req))
+ return;
- /* the completion code kicks us in case we hit this */
- if (blk_queue_start_tag(q, rq))
- break;
+ tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC);
+ if (!tcmd) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ mutex_lock(&qdata->cmd_req_mutex);
- spin_unlock_irq(q->queue_lock);
- if (scsi_tgt_uspace_send(cmd, tcmd->lun, GFP_ATOMIC) < 0)
- goto requeue;
- spin_lock_irq(q->queue_lock);
+ spin_lock_irqsave(&qdata->cmd_req_lock, flags);
+ if (list_empty(&qdata->cmd_req)) {
+ spin_unlock_irqrestore(&qdata->cmd_req_lock, flags);
+ mutex_unlock(&qdata->cmd_req_mutex);
+ kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
+ goto out;
}
+ rq = list_entry_rq(qdata->cmd_req.next);
+ list_del_init(&rq->queuelist);
+ spin_unlock_irqrestore(&qdata->cmd_req_lock, flags);
- return;
-requeue:
- spin_lock_irq(q->queue_lock);
- /* need to track cnts and plug */
- blk_requeue_request(q, rq);
- spin_unlock_irq(q->queue_lock);
+ if ((rq->flags & REQ_DONTPREP)) {
+ kmem_cache_free(scsi_tgt_cmd_cache, tcmd);
+ tcmd = rq->end_io_data;
+ } else
+ init_scsi_tgt_cmd(rq, tcmd);
+
+ cmd = rq->special;
+ err = scsi_tgt_uspace_send(cmd, tcmd->lun, GFP_ATOMIC);
+ if (err < 0) {
+ eprintk("failed to send: %p %d\n", cmd, err);
+
+ spin_lock_irqsave(&qdata->cmd_req_lock, flags);
+ list_add(&rq->queuelist, &qdata->cmd_req);
+ spin_unlock_irqrestore(&qdata->cmd_req_lock, flags);
+ }
+
+ mutex_unlock(&qdata->cmd_req_mutex);
+out:
+ /* TODO: proper error handling */
+ if (err < 0)
+ queue_delayed_work(scsi_tgtd, &qdata->uspace_send_work,
+ HZ / 10);
+ else
+ goto retry;
}
/**
@@ -150,13 +204,13 @@ int scsi_tgt_alloc_queue(struct Scsi_Hos
{
struct scsi_tgt_queuedata *queuedata;
struct request_queue *q;
- int err;
+ int err, i;
/*
* Do we need to send a netlink event or should uspace
* just respond to the hotplug event?
*/
- q = __scsi_alloc_queue(shost, scsi_uspace_request_fn);
+ q = __scsi_alloc_queue(shost, NULL);
if (!q)
return -ENOMEM;
@@ -168,19 +222,12 @@ int scsi_tgt_alloc_queue(struct Scsi_Hos
queuedata->shost = shost;
q->queuedata = queuedata;
- elevator_exit(q->elevator);
- err = elevator_init(q, "noop");
- if (err)
- goto free_data;
-
- blk_queue_prep_rq(q, scsi_uspace_prep_fn);
/*
* this is a silly hack. We should probably just queue as many
* command as is recvd to userspace. uspace can then make
* sure we do not overload the HBA
*/
q->nr_requests = shost->hostt->can_queue;
- blk_queue_init_tags(q, shost->hostt->can_queue, NULL);
/*
* We currently only support software LLDs so this does
* not matter for now. Do we need this for the cards we support?
@@ -189,10 +236,17 @@ int scsi_tgt_alloc_queue(struct Scsi_Hos
blk_queue_dma_alignment(q, 0);
shost->uspace_req_q = q;
+ for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++)
+ INIT_LIST_HEAD(&queuedata->cmd_hash[i]);
+ spin_lock_init(&queuedata->cmd_hash_lock);
+
+ INIT_LIST_HEAD(&queuedata->cmd_req);
+ spin_lock_init(&queuedata->cmd_req_lock);
+ INIT_WORK(&queuedata->uspace_send_work, scsi_tgt_uspace_send_fn, q);
+ mutex_init(&queuedata->cmd_req_mutex);
+
return 0;
-free_data:
- kfree(queuedata);
cleanup_queue:
blk_cleanup_queue(q);
return err;
@@ -215,14 +269,17 @@ EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host);
void scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun,
int noblock)
{
- /*
- * For now this just calls the request_fn from this context.
- * For HW llds though we do not want to execute from here so
- * the elevator code needs something like a REQ_TGT_CMD or
- * REQ_MSG_DONT_UNPLUG_IMMED_BECUASE_WE_WILL_HANDLE_IT
- */
+ struct request_queue *q = cmd->request->q;
+ struct scsi_tgt_queuedata *qdata = q->queuedata;
+ unsigned long flags;
+
cmd->request->end_io_data = scsilun;
- elv_add_request(cmd->request->q, cmd->request, ELEVATOR_INSERT_BACK, 1);
+
+ spin_lock_irqsave(&qdata->cmd_req_lock, flags);
+ list_add_tail(&cmd->request->queuelist, &qdata->cmd_req);
+ spin_unlock_irqrestore(&qdata->cmd_req_lock, flags);
+
+ queue_work(scsi_tgtd, &qdata->uspace_send_work);
}
EXPORT_SYMBOL_GPL(scsi_tgt_queue_command);
@@ -438,6 +495,27 @@ static int scsi_tgt_copy_sense(struct sc
return 0;
}
+static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u32 cid)
+{
+ struct scsi_tgt_queuedata *qdata = q->queuedata;
+ struct request *rq = NULL;
+ struct list_head *head;
+ struct scsi_tgt_cmd *tcmd;
+ unsigned long flags;
+
+ head = &qdata->cmd_hash[cmd_hashfn(cid)];
+ spin_lock_irqsave(&qdata->cmd_hash_lock, flags);
+ list_for_each_entry(tcmd, head, hash_list) {
+ if (tcmd->rq->tag == cid) {
+ rq = tcmd->rq;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
+
+ return rq;
+}
+
int scsi_tgt_kspace_exec(int host_no, u32 cid, int result, u32 len,
unsigned long uaddr, u8 rw)
{
@@ -456,7 +534,7 @@ int scsi_tgt_kspace_exec(int host_no, u3
return -EINVAL;
}
- rq = blk_queue_find_tag(shost->uspace_req_q, cid);
+ rq = tgt_cmd_hash_lookup(shost->uspace_req_q, cid);
if (!rq) {
printk(KERN_ERR "Could not find cid %u\n", cid);
err = -EINVAL;
diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h
index fcf2ec6..6fedcec 100644
--- a/drivers/scsi/scsi_tgt_priv.h
+++ b/drivers/scsi/scsi_tgt_priv.h
@@ -11,10 +11,6 @@ do { \
#define eprintk dprintk
-struct scsi_tgt_queuedata {
- struct Scsi_Host *shost;
-};
-
extern void scsi_tgt_if_exit(void);
extern int scsi_tgt_if_init(void);
--
1.1.5
^ permalink raw reply related
* [PATCH 01/10] block layer: revoke the original patch to add partial mappings support
From: FUJITA Tomonori @ 2006-04-10 1:49 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
For target mode we could end up with the case where we get very large
request from the initiator. The request could be so large that we
cannot transfer all the data in one operation. For example the
HBA's segment or max_sector limits might limit us to a 1 MB transfer.
To send a 5 MB command then we need to transfer the command chunk by chunk.
To do this, tgt core will map in as much data as possible into a bio,
send this off, then when that transfer is completed we send off another
request/bio. To be able to pack as much data into a bio as possible
we need bio_map_user to support partially mapped bios.
Following the comments from Jens on the original patch:
http://marc.theaimsgroup.com/?l=linux-scsi&m=114012008928530&w=2
This patch will revoke changes by the original patch.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
block/ll_rw_blk.c | 5 ++---
fs/bio.c | 11 ++++-------
include/linux/bio.h | 5 ++---
3 files changed, 8 insertions(+), 13 deletions(-)
4d84a7a7218de12ef1e3f58a0a5514a730994848
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 13c40a0..03d9c82 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -2287,7 +2287,7 @@ int blk_rq_map_user(request_queue_t *q,
*/
uaddr = (unsigned long) ubuf;
if (!(uaddr & queue_dma_alignment(q)) && !(len & queue_dma_alignment(q)))
- bio = bio_map_user(q, NULL, uaddr, len, reading, 0);
+ bio = bio_map_user(q, NULL, uaddr, len, reading);
else
bio = bio_copy_user(q, uaddr, len, reading);
@@ -2339,8 +2339,7 @@ int blk_rq_map_user_iov(request_queue_t
/* we don't allow misaligned data like bio_map_user() does. If the
* user is using sg, they're expected to know the alignment constraints
* and respect them accordingly */
- bio = bio_map_user_iov(q, NULL, iov, iov_count, rq_data_dir(rq)== READ,
- 0);
+ bio = bio_map_user_iov(q, NULL, iov, iov_count, rq_data_dir(rq)== READ);
if (IS_ERR(bio))
return PTR_ERR(bio);
diff --git a/fs/bio.c b/fs/bio.c
index 3e940c9..d8259d9 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -718,21 +718,19 @@ static struct bio *__bio_map_user_iov(re
* @uaddr: start of user address
* @len: length in bytes
* @write_to_vm: bool indicating writing to pages or not
- * @support_partial: support partial mappings
*
* Map the user space address into a bio suitable for io to a block
* device. Returns an error pointer in case of error.
*/
struct bio *bio_map_user(request_queue_t *q, struct block_device *bdev,
- unsigned long uaddr, unsigned int len, int write_to_vm,
- int support_partial)
+ unsigned long uaddr, unsigned int len, int write_to_vm)
{
struct sg_iovec iov;
iov.iov_base = (void __user *)uaddr;
iov.iov_len = len;
- return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, support_partial);
+ return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm);
}
/**
@@ -742,14 +740,13 @@ struct bio *bio_map_user(request_queue_t
* @iov: the iovec.
* @iov_count: number of elements in the iovec
* @write_to_vm: bool indicating writing to pages or not
- * @support_partial: support partial mappings
*
* Map the user space address into a bio suitable for io to a block
* device. Returns an error pointer in case of error.
*/
struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev,
struct sg_iovec *iov, int iov_count,
- int write_to_vm, int support_partial)
+ int write_to_vm)
{
struct bio *bio;
int len = 0, i;
@@ -770,7 +767,7 @@ struct bio *bio_map_user_iov(request_que
for (i = 0; i < iov_count; i++)
len += iov[i].iov_len;
- if (bio->bi_size == len || support_partial)
+ if (bio->bi_size == len)
return bio;
/*
diff --git a/include/linux/bio.h b/include/linux/bio.h
index fc0906c..b60ffe3 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -295,13 +295,12 @@ extern int bio_add_page(struct bio *, st
extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
unsigned int, unsigned int);
extern int bio_get_nr_vecs(struct block_device *);
-extern int __bio_get_nr_vecs(struct request_queue *);
extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
- unsigned long, unsigned int, int, int);
+ unsigned long, unsigned int, int);
struct sg_iovec;
extern struct bio *bio_map_user_iov(struct request_queue *,
struct block_device *,
- struct sg_iovec *, int, int, int);
+ struct sg_iovec *, int, int);
extern void bio_unmap_user(struct bio *);
extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
gfp_t);
--
1.1.5
^ permalink raw reply related
* [Bluez-devel] Is there a existing test suite for bluez stack on bluez website?
From: Wang, Jing J @ 2006-04-10 1:40 UTC (permalink / raw)
To: bluez-devel
[-- Attachment #1: Type: text/plain, Size: 239 bytes --]
Hi,
Per job requirement, I need test bluez Bluetooth stack. I don't
plan to develop a test suite from scratch. So, is there any existing
test suite I can use for bluez?
Thanks in advance.
WangJing
[-- Attachment #2: Type: text/html, Size: 4914 bytes --]
^ permalink raw reply
* Re: [PATCH] fix de_thread() vs do_coredump() deadlock
From: Roland McGrath @ 2006-04-10 1:36 UTC (permalink / raw)
To: Oleg Nesterov
Cc: linux-kernel, Ingo Molnar, Michael Kerrisk, Linus Torvalds,
Andrew Morton
In-Reply-To: <434E906E.85BD86BF@tv-sign.ru>
Sorry I have been absent from the discussion for such a long time.
I'm trying to catch up on old issues that I should have reviewed earlier.
This is about Oleg's change, commit 1291cf4163d21f1b4999d697cbf68d38e7151c28.
Your change is sensible on its own terms and clearly it resolves the
deadlock. But thinking about this made me realize that we have a more
general problem with this kind of race condition. The coredump deadlock is
the worst failure mode, but in non-coredump fatal signals we were already
getting the semantics wrong in the same race condition. That is, the fatal
signal should never be dropped on the floor. If the exec wins the race,
then any signals not yet acted on should remain queued. Before your patch
this race scenario would hit the deadlock in the coredump case. Now, the
coredump case matches the non-coredump fatal signal: the signal is dropped
on the floor. This violates POSIX, which says that signals pending for the
process are preserved across exec. (There might even be some way to abuse
this, though it seems like a bit of a stretch off hand.)
What do you think about this patch? I think it's the correct thing to do,
and a bit of a cleanup not to use SIGNAL_GROUP_EXIT for exec. The
do_coredump part of the patch can be cleaned up nicely in concert with some
of the other coredump changes you have posted recently. In de_thread, I
wanted to get rid of taking tasklist_lock, which is no longer needed by
zap_other_threads these days. But I didn't really know the story on the
child_reaper magic there that seems still to need the lock. (Note that for
the ptrace corner cases not to lose signals either, we also need the patch
I posted to revert most of commit 30e0fca6c1d7d26f3f2daa4dd2b12c51dadc778a.)
By reverting the 1291cf4163d21f1b4999d697cbf68d38e7151c28 change, I was
able to reproduce the deadlock. With that patch restored, I then verified
that in some of the races, a fatal signal was dropped on the floor. In the
same tests using the patch below, there was never a deadlock or a lost signal.
Thanks,
Roland
[PATCH] Fix race between exec and fatal signals
When we have a race between an exec and another thread in the same group
dequeuing a fatal signal, the signal loses and the exec goes through. The
problem here is that the signal is lost entirely. In some circumstances
this violates POSIX, which says that signals pending for the process
(i.e. on the group's shared_pending queue) are preserved across exec.
This might even be abusable to some extent, though it's hard to see much
real damage being done.
There is no problem when signals remain queued, as they will be seen after
the exec. The problematic race is when a signal has been dequeued by some
thread and is then dropped on floor when the thread decides to go and die
for the exec instead. I think the correct solution is for the exec to
always lose that race.
This patch adds a SIGNAL_GROUP_EXEC flag to distinguish de_thread from a
true group exit that will be fatal to all threads (SIGNAL_GROUP_EXIT).
When an exec is waiting for threads to die and another thread tries to do a
group exit, it aborts the exec so the exec'ing thread will die with the others.
Signed-off-by: Roland McGrath <roland@redhat.com>
---
fs/exec.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
include/linux/sched.h | 3 ++-
kernel/exit.c | 5 +++--
kernel/fork.c | 3 ++-
kernel/signal.c | 31 ++++++++++++++++++++++++-------
5 files changed, 71 insertions(+), 19 deletions(-)
ced7c831060aadb6f2dbb15f36391e84061f5720
diff --git a/fs/exec.c b/fs/exec.c
index 0291a68..eae6371 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -606,15 +606,16 @@ static int de_thread(struct task_struct
*/
read_lock(&tasklist_lock);
spin_lock_irq(lock);
- if (sig->flags & SIGNAL_GROUP_EXIT) {
+ if (unlikely(sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC))) {
/*
* Another group action in progress, just
* return so that the signal is processed.
*/
- spin_unlock_irq(lock);
read_unlock(&tasklist_lock);
+ dying:
+ spin_unlock_irq(lock);
kmem_cache_free(sighand_cachep, newsighand);
- return -EAGAIN;
+ return -ERESTARTNOINTR;
}
/*
@@ -625,7 +626,7 @@ static int de_thread(struct task_struct
if (unlikely(current->group_leader == child_reaper))
child_reaper = current;
- zap_other_threads(current);
+ zap_other_threads(current, SIGNAL_GROUP_EXEC);
read_unlock(&tasklist_lock);
/*
@@ -646,6 +647,17 @@ static int de_thread(struct task_struct
if (hrtimer_cancel(&sig->real_timer))
hrtimer_restart(&sig->real_timer);
spin_lock_irq(lock);
+ if (unlikely(!(sig->flags & SIGNAL_GROUP_EXEC))) {
+ BUG_ON(!(sig->flags & SIGNAL_GROUP_EXIT));
+ /*
+ * Oh, dear. Our exec was cancelled by a group
+ * exit during the window where we released the
+ * lock to update the timer. Since we know we are
+ * all about to die, it doesn't matter that the
+ * timer now points at us.
+ */
+ goto dying;
+ }
}
while (atomic_read(&sig->count) > count) {
sig->group_exit_task = current;
@@ -654,6 +666,14 @@ static int de_thread(struct task_struct
spin_unlock_irq(lock);
schedule();
spin_lock_irq(lock);
+ if (unlikely(!(sig->flags & SIGNAL_GROUP_EXEC))) {
+ BUG_ON(!(sig->flags & SIGNAL_GROUP_EXIT));
+ BUG_ON(sig->group_exit_task == current);
+ /*
+ * Our exec was cancelled by a group exit.
+ */
+ goto dying;
+ }
}
sig->group_exit_task = NULL;
sig->notify_count = 0;
@@ -1480,10 +1500,22 @@ int do_coredump(long signr, int exit_cod
retval = -EAGAIN;
spin_lock_irq(¤t->sighand->siglock);
- if (!(current->signal->flags & SIGNAL_GROUP_EXIT)) {
- current->signal->flags = SIGNAL_GROUP_EXIT;
- current->signal->group_exit_code = exit_code;
- current->signal->group_stop_count = 0;
+ if (likely(!(current->signal->flags & SIGNAL_GROUP_EXIT))) {
+ struct signal_struct *sig = current->signal;
+ /*
+ * If there is an exec in progress, cancel it and wake
+ * up the exec'ing thread to feel our imminent zapping.
+ */
+ if (unlikely(sig->flags & SIGNAL_GROUP_EXEC)) {
+ struct task_struct *execer = sig->group_exit_task;
+ sigaddset(&execer->pending.signal, SIGKILL);
+ sig->group_exit_task = NULL;
+ sig->notify_count = 0;
+ wake_up_process(execer);
+ }
+ sig->flags = SIGNAL_GROUP_EXIT;
+ sig->group_exit_code = exit_code;
+ sig->group_stop_count = 0;
retval = 0;
}
spin_unlock_irq(¤t->sighand->siglock);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 541f482..1f5d7ab 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -463,6 +463,7 @@ struct signal_struct {
#define SIGNAL_STOP_DEQUEUED 0x00000002 /* stop signal dequeued */
#define SIGNAL_STOP_CONTINUED 0x00000004 /* SIGCONT since WCONTINUED reap */
#define SIGNAL_GROUP_EXIT 0x00000008 /* group exit in progress */
+#define SIGNAL_GROUP_EXEC 0x00000010 /* group-killing exec in progress */
/*
@@ -1102,7 +1103,7 @@ extern void do_notify_parent(struct task
extern void force_sig(int, struct task_struct *);
extern void force_sig_specific(int, struct task_struct *);
extern int send_sig(int, struct task_struct *, int);
-extern void zap_other_threads(struct task_struct *p);
+extern void zap_other_threads(struct task_struct *p, int);
extern int kill_pg(pid_t, int, int);
extern int kill_proc(pid_t, int, int);
extern struct sigqueue *sigqueue_alloc(void);
diff --git a/kernel/exit.c b/kernel/exit.c
index 6c2eeb8..176c641 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -826,7 +826,8 @@ static void exit_notify(struct task_stru
state = EXIT_ZOMBIE;
if (tsk->exit_signal == -1 &&
(likely(tsk->ptrace == 0) ||
- unlikely(tsk->parent->signal->flags & SIGNAL_GROUP_EXIT)))
+ unlikely(tsk->parent->signal->flags
+ & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC))))
state = EXIT_DEAD;
tsk->exit_state = state;
@@ -989,7 +990,7 @@ do_group_exit(int exit_code)
exit_code = sig->group_exit_code;
else {
sig->group_exit_code = exit_code;
- zap_other_threads(current);
+ zap_other_threads(current, SIGNAL_GROUP_EXIT);
}
spin_unlock_irq(&sighand->siglock);
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 3384eb8..8276618 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1167,7 +1167,8 @@ static task_t *copy_process(unsigned lon
* do not create this new thread - the whole thread
* group is supposed to exit anyway.
*/
- if (current->signal->flags & SIGNAL_GROUP_EXIT) {
+ if (current->signal->flags
+ & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC)) {
spin_unlock(¤t->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -EAGAIN;
diff --git a/kernel/signal.c b/kernel/signal.c
index 0492c04..b59154b 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -465,7 +465,8 @@ int dequeue_signal(struct task_struct *t
* is to alert stop-signal processing code when another
* processor has come along and cleared the flag.
*/
- if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT))
+ if (!(tsk->signal->flags
+ & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC)))
tsk->signal->flags |= SIGNAL_STOP_DEQUEUED;
}
if ( signr &&
@@ -604,7 +605,7 @@ static void handle_stop_signal(int sig,
{
struct task_struct *t;
- if (p->signal->flags & SIGNAL_GROUP_EXIT)
+ if (p->signal->flags & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC))
/*
* The process is in the middle of dying already.
*/
@@ -887,7 +888,8 @@ __group_complete_signal(int sig, struct
* Found a killable thread. If the signal will be fatal,
* then start taking the whole group down immediately.
*/
- if (sig_fatal(p, sig) && !(p->signal->flags & SIGNAL_GROUP_EXIT) &&
+ if (sig_fatal(p, sig) &&
+ !(p->signal->flags & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC)) &&
!sigismember(&t->real_blocked, sig) &&
(sig == SIGKILL || !(t->ptrace & PT_PTRACED))) {
/*
@@ -975,12 +977,26 @@ __group_send_sig_info(int sig, struct si
/*
* Nuke all other threads in the group.
+ * tasklist_lock is not needed here, but p->sighand->siglock must be held.
*/
-void zap_other_threads(struct task_struct *p)
+void zap_other_threads(struct task_struct *p, int flag)
{
struct task_struct *t;
- p->signal->flags = SIGNAL_GROUP_EXIT;
+ if (unlikely(p->signal->flags & SIGNAL_GROUP_EXEC)) {
+ /*
+ * We are cancelling an exec that is in progress, to let
+ * the thread group die instead. We need to wake the
+ * exec'ing thread up from uninterruptible wait.
+ */
+ BUG_ON(flag != SIGNAL_GROUP_EXIT);
+ t = p->signal->group_exit_task;
+ p->signal->group_exit_task = NULL;
+ p->signal->notify_count = 0;
+ wake_up_process(t);
+ }
+
+ p->signal->flags = flag;
p->signal->group_stop_count = 0;
if (thread_group_empty(p))
@@ -1564,7 +1580,8 @@ static void ptrace_stop(int exit_code, i
likely(current->parent != current->real_parent ||
!(current->ptrace & PT_ATTACHED)) &&
(likely(current->parent->signal != current->signal) ||
- !unlikely(current->signal->flags & SIGNAL_GROUP_EXIT))) {
+ !unlikely(current->signal->flags
+ & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC)))) {
do_notify_parent_cldstop(current, CLD_TRAPPED);
read_unlock(&tasklist_lock);
schedule();
@@ -1705,7 +1722,7 @@ static int handle_group_stop(void)
return 0;
}
- if (current->signal->flags & SIGNAL_GROUP_EXIT)
+ if (current->signal->flags & (SIGNAL_GROUP_EXIT | SIGNAL_GROUP_EXEC))
/*
* Group stop is so another thread can do a core dump,
* or else we are racing against a death signal.
^ permalink raw reply related
* Re: alpha DEAD on >=2.6.16-rc3
From: Wakko Warner @ 2006-04-10 1:36 UTC (permalink / raw)
To: leonie herzberg; +Cc: linux-kernel
In-Reply-To: <44397596.5020809@net4u.de>
leonie herzberg wrote:
> Hi. I already posted a bugreport on the bugzilla
> (http://bugzilla.kernel.org/show_bug.cgi?id=6351) but I feel no one is
> recognizing that; and as I see it, it's a rather hard bug since it
> throws a kernel panic immediately at boot time. I believe it has to do
> with the change made in 2.6.16-rc3 concerning "cpu_possible_map". None
> of the newer kernel versions works.
> As you can see at the first (and up to now, only) comment, this is not
> only my problem.
> Maybe it appears only in connection with SMP. I can't tell.
I'm not sure if this is similar or not. I compiled 2.6.16 for my alpha 2
days ago. I've had nothing but lockup/halting problems with it and went back
to 2.4.
This is a noritake machine (alphaserver 1000a 4/266) 160mb ram and a mylex
dac960pdu (IIRC) raid controller.
--
Lab tests show that use of micro$oft causes cancer in lab animals
Got Gas???
^ permalink raw reply
* Re: [PATCH 0/7] uts namespaces: Introduction
From: Sam Vilain @ 2006-04-10 1:15 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: linux-kernel, Kirill Korotaev, herbert, devel, Eric W. Biederman,
xemul, James Morris
In-Reply-To: <20060407234815.849357768@sergelap>
Serge,
I have just imported your series into the GIT repository where I have
been collating the various recent related submissions at:
git://vserver.utsl.gen.nz/vserver
A summary of the submissions imported to date are at:
http://www.utsl.gen.nz/gitweb/?p=vserver;a=heads
I will endeavour to continue to collect and catalogue all vserver
related submissions I receive, see on LKML, or get pull requests for, as
a part of my efforts to merge this functionality.
Sam.
Serge E. Hallyn wrote:
>Introduce utsname namespaces. Instead of a single system_utsname
>containing hostname domainname etc, a process can request it's
>copy of the uts info to be cloned. The data will be copied from
>it's original, but any further changes will not be seen by processes
>which are not it's children, and vice versa.
>
>This is useful, for instance, for vserver/openvz, which can now clone
>a new uts namespace for each new virtual server.
>
>Aside from the debugging patch which comes last, this patchset does
>not actually implement a way for processes to unshare the uts namespace.
>The proper unsharing semantics are to be worked out later.
>
>Changes since last submission:
> Restructured patchset so it compiles after each patch
> Removed EXPORT_SYMBOL for unshare_uts_ns and free_uts_ns.
> The former is now in the debugging pach and the latter gone
> entirely, as unsharing is likely not something to be done
> from modules!
>
>-serge
>
>
>
>
^ permalink raw reply
* Re: Parallel port problems on Sun Ultra10
From: Raphael Assenat @ 2006-04-10 1:10 UTC (permalink / raw)
To: sparclinux
In-Reply-To: <1144596830.4439295e52873@imp1-g19.free.fr>
On Sun, Apr 09, 2006 at 05:33:50PM +0200, Christophe Jacquet wrote:
> When I type " echo 'Hello world' >/dev/lp0 ", I get the message:
>
> lp0: ECP mode
>
> The string gets printed on the printer.
>
> Then, Linux crashes. I get no more messages. The Bash prompt never comes back. I
> can interact with OBP by hitting "Stop-A", and reboot the machine.
Hi,
this reminds me of a problem I had a few week ago while playing with
an homebuild parallel port project. The machine would lock totally, but
as soon as I disconnected the circuit from the port the machine would
unlock.
Maybe you could try disconnecting the printer and see what happens?
Here are more details about the problem I observed:
When the parallel port interrupt is enabled, the machine hangs as long as
the ACK pin is held low. I observed that the parport interrupt count in
/proc/interrupt were higher after each hang.
It looks to me like the parport interrupt is level triggered instead
of edge triggered. I wanted try on x86 hardware to see if the problem
also happens before posting, but I decided to post anyway when I saw
this message.
I observed this on a 2.6.16-rc6-git-something.
Regards,
Raphael Assenat
^ permalink raw reply
* Re: linear writes to raid5
From: Neil Brown @ 2006-04-10 0:50 UTC (permalink / raw)
To: Alex Tomas; +Cc: linux-raid
In-Reply-To: <m37j60udi8.fsf@bzzz.home.net>
On Saturday April 8, alex@clusterfs.com wrote:
>
> Good day all,
>
> is there a way to batch explicitely write requests raid5 issues?
> for example, there is a raid5 built from 3 disks with chunk=64K.
> one types dd if=/dev/zero of=/dev/md0 bs=128k count=1 and 128K
> bio gets into the raid5. raid5 processes the request, does xor
> for parity stripe, then issues 2 64KB requests down to lower level.
>
> is it even possible to implement? if so, how complex?
>
> I suppose we could introduce a context which holds last
> non-issued bio and instead of generic_make_request() in
> handle_stripe() try to merge current request to the previous
> one from the context? how does this sound to you?
The raid5 code attempts to do this already, though I'm not sure how
successful it is. I think it is fairly successful, but not completely
successful.
There is a trade-off that raid5 has to make. Waiting longer can mean
more blocks on the same stripe, and so less reads. But waiting longer
can also increase latency which might not be good.
The thing to would be to put some tracing in to find out exactly what
is happening for some sample workloads, and then see if anything can
be improved.
NeilBrown
^ permalink raw reply
* Adds HDA support for Intel D945Pvs board subdevice id 0x0707
From: Ashley Clark @ 2006-04-10 0:42 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 479 bytes --]
Sorry about the last message, not sure if it had the attachment in it.
Signed-Off-By: Ashley Clark <aclark@ghoti.org>
Summary: Adds HDA support for Intel D945Pvs board with subdevice id
0x0707
This patch adds the entry for the 5-stack pin-config for the STAC
chip on the Intel D945Pvs board with subdevice id 0x0707.
With this patch against 1.0.11rc4 in the linux kernel 2.6.17-rc1, I'm
able to successfully output over the optical port and analog ports.
Ashley Clark
[-- Attachment #2: sigmatel.diff --]
[-- Type: application/octet-stream, Size: 616 bytes --]
--- patch_sigmatel.c.aclark 2006-04-09 14:49:38.000000000 -0500
+++ patch_sigmatel.c 2006-04-09 15:38:35.000000000 -0500
@@ -310,6 +310,9 @@
.pci_subdevice = 0x0b0b,
.config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack, 9221 A1 */
{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+ .pci_subdevice = 0x0707,
+ .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */
+ { .pci_subvendor = PCI_VENDOR_ID_INTEL,
.pci_subdevice = 0x0404,
.config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */
{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
[-- Attachment #3: Type: text/plain, Size: 2 bytes --]
^ permalink raw reply
* Re: [PATCH 2.6.17-rc1-mm1] m32r: Fix cpu_possible_map and cpu_present_map initialization for SMP kernel
From: Hirokazu Takata @ 2006-04-10 0:37 UTC (permalink / raw)
To: akpm; +Cc: takata, linux-kernel, fujiwara
In-Reply-To: <20060407150337.7cc0c462.akpm@osdl.org>
From: Andrew Morton <akpm@osdl.org>
Date: Fri, 07 Apr 2006 15:03:37 -0700
> Hirokazu Takata <takata@linux-m32r.org> wrote:
> >
> > This patch fixes a boot problem of the m32r SMP kernel
> > 2.6.16-rc1-mm3 or later.
>
> This sounds like something which needs to be backported into 2.6.16.x,
> correct?
>
> Also, should "m32r: security fix of {get,put}_user macros" go into 2.6.16.x?
Yes, please include this into 2.6.16.x.
Thanks,
-- Takata
^ permalink raw reply
* Re: [-mm patch] drivers/pci/hotplug/acpiphp_glue.c: make a function static
From: MUNEDA Takahiro @ 2006-04-10 0:27 UTC (permalink / raw)
To: Adrian Bunk
Cc: Andrew Morton, MUNEDA Takahiro, Greg Kroah-Hartman, linux-kernel,
linux-pci
In-Reply-To: <20060409145047.GC8454@stusta.de>
At Sun, 9 Apr 2006 16:50:47 +0200,
Adrian Bunk <bunk@stusta.de> wrote:
>
> On Sat, Apr 08, 2006 at 03:14:05AM -0700, Andrew Morton wrote:
> >...
> > Changes since 2.6.17-rc1-mm1:
> >...
> > +gregkh-pci-acpiphp-configure-_prt-v3.patch
> >...
> > PCI tree updates
> >...
>
> This patch makes the needlessly global acpiphp_bus_trim() static.
Good catch. This patch looks good to me.
> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Acked-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
Thanks,
MUNE
^ permalink raw reply
* Re: [PATCH 3/19] kconfig: recenter menuconfig
From: Randy.Dunlap @ 2006-04-10 0:33 UTC (permalink / raw)
To: Andrew Morton; +Cc: ncunningham, zippel, sam, linux-kernel
In-Reply-To: <20060409153914.3fb468d3.akpm@osdl.org>
On Sun, 9 Apr 2006 15:39:14 -0700 Andrew Morton wrote:
> Nigel Cunningham <ncunningham@cyclades.com> wrote:
> >
> > Hi.
> >
> > On Monday 10 April 2006 08:10, Roman Zippel wrote:
> > > Hi,
> > >
> > > On Sun, 9 Apr 2006, Sam Ravnborg wrote:
> > > > > Further there is now a mix of left aligned and centered output,
> > > > > which is ugly
> > > >
> > > > So we should fix the rest too instead of reintroducing the old
> > > > behaviour.
> > >
> > > Well, I prefer the old behaviour.
> >
> > I don't know if you want 2c worth from other people, but I liked menuconfig
> > much better when it was more centred. This new
> > 'everything-hard-against-the-left-margin' look is ugly, IMHO :)
> >
>
> It hardly seems to matter, given that the colours we use make the text
> invisible anyway..
You (anyone) can get alternate colors or monochrome here:
http://www.xenotime.net/linux/patches/menuconfig-altcolor-mono.patch
The yellow highlight character shows up poorly for me. OTOH, I doubt that
any one color scheme would be good for everyone.
---
~Randy
^ permalink raw reply
* Adds HDA support for Intel D945Pvs board subdevice id 0x0707
From: Ashley Clark @ 2006-04-10 0:30 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1.1: Type: text/plain, Size: 381 bytes --]
Signed-Off-By: Ashley Clark <aclark@ghoti.org>
Summary: Adds HDA support for Intel D945Pvs board with subdevice id
0x0707
This patch adds the 5-stack pin-config for the STAC chip on the Intel
D945Pvs board with subdevice id 0x0707.
With this patch against 1.0.11rc4, I'm able to successfully output
over the optical port and analog ports.
Ashley Clark

[-- Attachment #1.2.1: Type: text/html, Size: 2950 bytes --]
[-- Attachment #1.2.2: sigmatel.diff --]
[-- Type: application/octet-stream, Size: 616 bytes --]
--- patch_sigmatel.c.aclark 2006-04-09 14:49:38.000000000 -0500
+++ patch_sigmatel.c 2006-04-09 15:38:35.000000000 -0500
@@ -310,6 +310,9 @@
.pci_subdevice = 0x0b0b,
.config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack, 9221 A1 */
{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
+ .pci_subdevice = 0x0707,
+ .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */
+ { .pci_subvendor = PCI_VENDOR_ID_INTEL,
.pci_subdevice = 0x0404,
.config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */
{ .pci_subvendor = PCI_VENDOR_ID_INTEL,
[-- Attachment #1.2.3: Type: text/html, Size: 650 bytes --]
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2220 bytes --]
^ permalink raw reply
* [PATCH] bcm43xx-d80211: protect tx_stat callback from uninitialized device
From: Michael Buesch @ 2006-04-10 0:25 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w,
jbenc-AlSwsSmVLrQ
diff --git a/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c b/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
index 043a5cf..f0f4f78 100644
--- a/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
@@ -4128,15 +4128,19 @@ static int bcm43xx_net_get_tx_stats(stru
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
+ int err = -ENODEV;
bcm43xx_lock(bcm, flags);
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_get_tx_stats(bcm, stats);
- else
- bcm43xx_dma_get_tx_stats(bcm, stats);
+ if (likely(bcm->initialized)) {
+ if (bcm43xx_using_pio(bcm))
+ bcm43xx_pio_get_tx_stats(bcm, stats);
+ else
+ bcm43xx_dma_get_tx_stats(bcm, stats);
+ err = 0;
+ }
bcm43xx_unlock(bcm, flags);
- return 0;
+ return err;
}
static int bcm43xx_net_get_stats(struct net_device *net_dev,
--
Greetings Michael.
^ permalink raw reply related
* bcm43xx symbol clash problems
From: Michael Buesch @ 2006-04-10 0:16 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
Hi,
I looked into the symbol clash problems between bcm43xx and bcm43xx-d80211
you mentioned at the wireless summit.
Well, IMHO it is pretty hard to find a good solution to this.
The situation is: We have several nonstatic functions in the bcm driver. These
functions have the same name in the softmac and dscape versions. It's quite a
lot of functions.
We can't make them static, because the driver is splitted over several files.
I would _really_ want to prevent renaming them all, because that is lots of work,
which will be thrown away anyway.
Does kbuild perhaps have some magic to handle that?
This needs to be solved soon, but I have no idea how.
I also wanna note that I am looking into using quilt for bcm43xx development.
git is not the perfect solution for bcm43xx development. Maybe quilt is.
Who knows... Let's try it.
--
Greetings Michael, who would like to have the namespace keyword in C.
^ permalink raw reply
* [PATCH] bcm43xx: use pci_iomap() for convenience.
From: Michael Buesch @ 2006-04-10 0:08 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
This reduces codesize.
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -648,7 +648,6 @@ struct bcm43xx_private {
unsigned int irq;
void __iomem *mmio_addr;
- unsigned int mmio_len;
/* Do not use the lock directly. Use the bcm43xx_lock* helper
* functions, to be MMIO-safe. */
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
@@ -92,7 +92,7 @@ static ssize_t devinfo_read_file(struct
fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
pci_dev->subsystem_vendor, pci_dev->subsystem_device);
fappend("IRQ: %d\n", bcm->irq);
- fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len);
+ fappend("mmio_addr: 0x%p\n", bcm->mmio_addr);
fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
fappend("Radio disabled by hardware!\n");
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -3287,8 +3287,7 @@ static void bcm43xx_detach_board(struct
bcm43xx_chipset_detach(bcm);
/* Do _not_ access the chip, after it is detached. */
- iounmap(bcm->mmio_addr);
-
+ pci_iounmap(pci_dev, bcm->mmio_addr);
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
@@ -3378,40 +3377,26 @@ static int bcm43xx_attach_board(struct b
struct net_device *net_dev = bcm->net_dev;
int err;
int i;
- unsigned long mmio_start, mmio_flags, mmio_len;
u32 coremask;
err = pci_enable_device(pci_dev);
if (err) {
- printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
+ printk(KERN_ERR PFX "pci_enable_device() failed\n");
goto out;
}
- mmio_start = pci_resource_start(pci_dev, 0);
- mmio_flags = pci_resource_flags(pci_dev, 0);
- mmio_len = pci_resource_len(pci_dev, 0);
- if (!(mmio_flags & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX
- "%s, region #0 not an MMIO resource, aborting\n",
- pci_name(pci_dev));
- err = -ENODEV;
- goto err_pci_disable;
- }
err = pci_request_regions(pci_dev, KBUILD_MODNAME);
if (err) {
- printk(KERN_ERR PFX
- "could not access PCI resources (%i)\n", err);
+ printk(KERN_ERR PFX "pci_request_regions() failed\n");
goto err_pci_disable;
}
/* enable PCI bus-mastering */
pci_set_master(pci_dev);
- bcm->mmio_addr = ioremap(mmio_start, mmio_len);
+ bcm->mmio_addr = pci_iomap(pci_dev, 0, ~0UL);
if (!bcm->mmio_addr) {
- printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
- pci_name(pci_dev));
+ printk(KERN_ERR PFX "pci_iomap() failed\n");
err = -EIO;
goto err_pci_release;
}
- bcm->mmio_len = mmio_len;
net_dev->base_addr = (unsigned long)bcm->mmio_addr;
bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
@@ -3504,7 +3489,7 @@ err_80211_unwind:
err_chipset_detach:
bcm43xx_chipset_detach(bcm);
err_iounmap:
- iounmap(bcm->mmio_addr);
+ pci_iounmap(pci_dev, bcm->mmio_addr);
err_pci_release:
pci_release_regions(pci_dev);
err_pci_disable:
--
Greetings Michael.
^ permalink raw reply
* Re: [PATCH] git log [diff-tree options]...
From: Linus Torvalds @ 2006-04-10 0:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Johannes Schindelin, git
In-Reply-To: <7vy7ye9uk8.fsf@assigned-by-dhcp.cox.net>
On Sun, 9 Apr 2006, Junio C Hamano wrote:
>
> I do not think so. You should default to --cc only there is no
> explicit command line stuff from the user.
Actually, even that would be wrong, when I think more about it. The
default for "git-whatchanged" is to do diffing, but default to the "raw"
diff (just "-r" for recursive).
So the most appropriate default set of flags is likely "-r -c", which also
means that any subsequent explicit command line stuff will override it (ie
adding a "-p" should automatically do the right thing).
But the "memmove()" to move the arguments around was definitely broken.
Much better to just initialize the diff flags manually, I think.
Linus
^ permalink raw reply
* [PATCH] bcm43xx-d80211: use pci_iomap() for convenience.
From: Michael Buesch @ 2006-04-10 0:05 UTC (permalink / raw)
To: linville-2XuSBdqkA4R54TAoqtyWWQ
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w
This reduces codesize.
--- a/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx-d80211/bcm43xx.h
@@ -639,7 +639,6 @@ struct bcm43xx_private {
unsigned int irq;
void __iomem *mmio_addr;
- unsigned int mmio_len;
/* Do not use the lock directly. Use the bcm43xx_lock* helper
* functions, to be MMIO-safe. */
--- a/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c
+++ b/drivers/net/wireless/bcm43xx-d80211/bcm43xx_debugfs.c
@@ -92,7 +92,7 @@ static ssize_t devinfo_read_file(struct
fappend("subsystem_vendor: 0x%04x subsystem_device: 0x%04x\n",
pci_dev->subsystem_vendor, pci_dev->subsystem_device);
fappend("IRQ: %d\n", bcm->irq);
- fappend("mmio_addr: 0x%p mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len);
+ fappend("mmio_addr: 0x%p\n", bcm->mmio_addr);
fappend("chip_id: 0x%04x chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
fappend("Radio disabled by hardware!\n");
--- a/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx-d80211/bcm43xx_main.c
@@ -3770,8 +3770,7 @@ static void bcm43xx_detach_board(struct
bcm43xx_chipset_detach(bcm);
/* Do _not_ access the chip, after it is detached. */
- iounmap(bcm->mmio_addr);
-
+ pci_iounmap(pci_dev, bcm->mmio_addr);
pci_release_regions(pci_dev);
pci_disable_device(pci_dev);
@@ -3845,40 +3844,26 @@ static int bcm43xx_attach_board(struct b
struct net_device *net_dev = bcm->net_dev;
int err;
int i;
- unsigned long mmio_start, mmio_flags, mmio_len;
u32 coremask;
err = pci_enable_device(pci_dev);
if (err) {
- printk(KERN_ERR PFX "unable to wake up pci device (%i)\n", err);
+ printk(KERN_ERR PFX "pci_enable_device() failed\n");
goto out;
}
- mmio_start = pci_resource_start(pci_dev, 0);
- mmio_flags = pci_resource_flags(pci_dev, 0);
- mmio_len = pci_resource_len(pci_dev, 0);
- if (!(mmio_flags & IORESOURCE_MEM)) {
- printk(KERN_ERR PFX
- "%s, region #0 not an MMIO resource, aborting\n",
- pci_name(pci_dev));
- err = -ENODEV;
- goto err_pci_disable;
- }
err = pci_request_regions(pci_dev, KBUILD_MODNAME);
if (err) {
- printk(KERN_ERR PFX
- "could not access PCI resources (%i)\n", err);
+ printk(KERN_ERR PFX "pci_request_regions() failed\n");
goto err_pci_disable;
}
/* enable PCI bus-mastering */
pci_set_master(pci_dev);
- bcm->mmio_addr = ioremap(mmio_start, mmio_len);
+ bcm->mmio_addr = pci_iomap(pci_dev, 0, ~0UL);
if (!bcm->mmio_addr) {
- printk(KERN_ERR PFX "%s: cannot remap MMIO, aborting\n",
- pci_name(pci_dev));
+ printk(KERN_ERR PFX "pci_iomap() failed\n");
err = -EIO;
goto err_pci_release;
}
- bcm->mmio_len = mmio_len;
net_dev->base_addr = (unsigned long)bcm->mmio_addr;
bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
@@ -3969,7 +3954,7 @@ err_80211_unwind:
err_chipset_detach:
bcm43xx_chipset_detach(bcm);
err_iounmap:
- iounmap(bcm->mmio_addr);
+ pci_iounmap(pci_dev, bcm->mmio_addr);
err_pci_release:
pci_release_regions(pci_dev);
err_pci_disable:
--
Greetings Michael.
^ permalink raw reply
* Re: [ANNOUNCE][RFC] PlugSched-6.3.1 for 2.6.16-rc5
From: Peter Williams @ 2006-04-09 23:53 UTC (permalink / raw)
To: Al Boldi; +Cc: linux-kernel
In-Reply-To: <200604090804.40867.a1426z@gawab.com>
Al Boldi wrote:
> Peter Williams wrote:
>> Al Boldi wrote:
>>> This is especially visible in spa_no_frills, and spa_ws recovers from
>>> this lockup somewhat and starts exhibiting this problem as a choking
>>> behavior.
>>>
>>> Running '# top d.1 (then shift T)' on another vt shows this choking
>>> behavior as the proc gets boosted.
>> But anyway, based on the evidence, I think the problem is caused by the
>> fact that the eatm tasks are running to completion in less than one time
>> slice without sleeping and this means that they never have their
>> priorities reassessed.
>
> Yes.
>
>> The reason that spa_ebs doesn't demonstrate the
>> problem is that it uses a smaller time slice for the first time slice
>> that a task gets. The reason that it does this is that it gives newly
>> forked processes a fairly high priority and if they're left to run for a
>> full 120 msecs at that high priority they can hose the system. Having a
>> shorter first time slice gives the scheduler a chance to reassess the
>> task's priority before it does much damage.
>
> But how does this explain spa_no_frills setting promotion to max not having
> this problem?
I'm still puzzled by this. The only thing I can think of is that the
promotion mechanism is to simple in that it just moves all promotable
tasks up one slot without regard for how long they've been on the queue.
Doing this was a deliberate decision based on the desire to minimize
overhead and the belief that it wouldn't matter in the grand scheme of
things. I may do some experimenting with slightly more sophisticated
version.
Properly done, promotion should hardly ever occur but the cost would be
slightly more complex enqueue/dequeue operations. The current version
will do unnecessary promotions but it was felt this was more than
compensated for by the lower enqueue/dequeue costs. We'll see how a
more sophisticated version goes in terms of trade offs.
>
>> The reason that the other schedulers don't have this strategy is that I
>> didn't think that it was necessary. Obviously I was wrong and should
>> extend it to the other schedulers. It's doubtful whether this will help
>> a great deal with spa_no_frills as it is pure round robin and doesn't
>> reassess priorities except when nice changes of the task changes
>> policies.
>
> Would it hurt to add it to spa_no_frills and let the children inherit it?
That would be the plan :-)
>
>> This is one good reason not to use spa_no_frills on
>> production systems.
>
> spa_ebs is great, but rather bursty. Even setting max_ia_bonus=0 doesn't fix
> that. Is there a way to smooth it like spa_no_frills?
The principal determinant would be the smoothness of the yardstick.
This is supposed to represent the task with the highest (recent) CPU
usage rate per share and is used to determine how fairly CPU is being
distributed among the currently active tasks. Tasks are given a
priority based on how their CPU usage rate per share compares to this
yardstick. This means that as the system load and/or type of task
running changes the priorities of the tasks can change dramatically.
Is the burstiness that you're seeing just in the observed priorities or
is it associated with behavioural burstiness as well?
>
>> Perhaps you should consider creating a child
>> scheduler on top of it that meets your needs?
>
> Perhaps.
Good. I've been hoping that other interested parties might be
encouraged by the small interface to SPA children to try different ideas
for scheduling.
>
>> Anyway, an alternative (and safer) way to reduce the effects of this
>> problem (while your waiting for me to do the above change) is to reduce
>> the size of the time slice. The only bad effects of doing this is that
>> you'll do slightly worse (less than 1%) on kernbench.
>
> Actually, setting timeslice to 5,50,100 gives me better performance on
> kernbench. After closer inspection, I found 120ms a rather awkward
> timeslice whereas 5,50, and 100 exhibited a smoother and faster response,
> which may be machine dependent, thus the need for an autotuner.
When I had the SPA schedulers fully instrumented I did some long term
measurements of my work station and found that the average CPU burst for
all tasks was only a few msecs. The exceptions were some of the tasks
involved in building kernels. So the only bad effects of reducing the
time slice will be causing those tasks to have more context switches
than otherwise and this will slightly reduce their throughput.
One thing that could be played with here is to vary the time slice based
on the priority. This would be in the opposite direction to the normal
scheduler with higher priority tasks (i.e. those with lower prio values)
getting smaller time slices. The rationale being:
1. stop tasks that have been given large bonuses from shutting out other
tasks for too long, and
2. reduce the context switch rate for tasks that haven't received bonuses.
Because tasks that get large bonuses will have short CPU bursts they
should not be adversely effected (if this is done properly) as they will
(except in exceptional circumstances such as a change in behaviour)
surrender the CPU voluntarily before their reduced time slice has
expired. Imaginative use of the available statistics could make this
largely automatic but there would be a need to be aware that the
statistics can be distorted by the shorter time slices.
On the other hand, giving tasks without bonuses longer time slices
shouldn't adversely effect interactive performance as the interactive
tasks will (courtesy of their bonuses) preempt them.
Peter
--
Peter Williams pwil3058@bigpond.net.au
"Learning, n. The kind of ignorance distinguishing the studious."
-- Ambrose Bierce
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.